@@ -20,6 +20,7 @@ limitations under the License.
2020#endif // TF_LITE_STATIC_MEMORY
2121
2222#include < cstring>
23+ #include < new>
2324#include < type_traits>
2425#include < utility>
2526
@@ -111,6 +112,7 @@ TfLiteSparsity TfLiteSparsityClone(const TfLiteSparsity& src) {
111112 if (src.dim_metadata ) {
112113 dst.dim_metadata = reinterpret_cast <TfLiteDimensionMetadata*>(
113114 calloc (1 , sizeof (TfLiteDimensionMetadata) * src.dim_metadata_size ));
115+ if (src.dim_metadata_size > 0 && !dst.dim_metadata ) return TfLiteSparsity ();
114116 for (int i = 0 ; i < src.dim_metadata_size ; ++i) {
115117 dst.dim_metadata [i] = src.dim_metadata [i];
116118 dst.dim_metadata [i].array_segments =
@@ -129,6 +131,7 @@ TfLiteSparsity* TfLiteSparsityClone(const TfLiteSparsity* const src) {
129131 }
130132 TfLiteSparsity* dst =
131133 reinterpret_cast <TfLiteSparsity*>(calloc (1 , sizeof (TfLiteSparsity)));
134+ if (!dst) return nullptr ;
132135 *dst = TfLiteSparsityClone (*src);
133136 return dst;
134137}
@@ -147,6 +150,7 @@ TfLiteQuantization TfLiteQuantizationClone(const TfLiteQuantization& src) {
147150 break ;
148151 case kTfLiteAffineQuantization : {
149152 dst.params = calloc (1 , sizeof (TfLiteAffineQuantization));
153+ if (!dst.params ) return TfLiteQuantization ();
150154 const TfLiteAffineQuantization* const src_params =
151155 reinterpret_cast <TfLiteAffineQuantization*>(src.params );
152156 TfLiteAffineQuantization* const dst_params =
@@ -158,6 +162,7 @@ TfLiteQuantization TfLiteQuantizationClone(const TfLiteQuantization& src) {
158162 }
159163 case kTfLiteBlockwiseQuantization : {
160164 dst.params = calloc (1 , sizeof (TfLiteBlockwiseQuantization));
165+ if (!dst.params ) return TfLiteQuantization ();
161166 const TfLiteBlockwiseQuantization* const src_params =
162167 (TfLiteBlockwiseQuantization*)(src.params );
163168 TfLiteBlockwiseQuantization* const dst_params =
@@ -219,6 +224,9 @@ TfLiteFloatArray* TfLiteFloatArrayCopy(const TfLiteFloatArray* src) {
219224void TfLiteFloatArrayFree (TfLiteFloatArray* a) { TfLiteVarArrayFree (a); }
220225
221226void TfLiteTensorDataFree (TfLiteTensor* t) {
227+ if (t == nullptr ) {
228+ return ;
229+ }
222230 if (t->allocation_type == kTfLiteVariantObject && t->data .data ) {
223231 delete static_cast <VariantData*>(t->data .data );
224232 } else if (t->allocation_type == kTfLiteDynamic ||
@@ -238,6 +246,9 @@ void TfLiteTensorDataFree(TfLiteTensor* t) {
238246}
239247
240248void TfLiteQuantizationFree (TfLiteQuantization* quantization) {
249+ if (quantization == nullptr ) {
250+ return ;
251+ }
241252 if (quantization->type == kTfLiteAffineQuantization ) {
242253 TfLiteAffineQuantization* q_params =
243254 reinterpret_cast <TfLiteAffineQuantization*>(quantization->params );
@@ -294,6 +305,9 @@ void TfLiteSparsityFree(TfLiteSparsity* sparsity) {
294305}
295306
296307void TfLiteTensorFree (TfLiteTensor* t) {
308+ if (t == nullptr ) {
309+ return ;
310+ }
297311 TfLiteTensorDataFree (t);
298312 if (t->dims ) TfLiteIntArrayFree (t->dims );
299313 t->dims = nullptr ;
@@ -308,7 +322,7 @@ void TfLiteTensorFree(TfLiteTensor* t) {
308322 t->sparsity = nullptr ;
309323}
310324
311- TfLiteTensor TfLiteTensorClone (const TfLiteTensor src) {
325+ TfLiteTensor TfLiteTensorClone (TfLiteTensor src) {
312326 // We copy all of the source data first, then we clone the fields that can't
313327 // be shared between two tensor instances.
314328 TfLiteTensor dst = src;
@@ -335,16 +349,18 @@ TfLiteTensor TfLiteTensorClone(const TfLiteTensor src) {
335349 break ;
336350 case kTfLiteAllocationStrategyMalloc :
337351 dst.data .data = malloc (src.bytes );
352+ if (src.bytes > 0 && !dst.data .data ) return TfLiteTensor ();
338353 std::memcpy (dst.data .data , src.data .data , src.bytes );
339354 break ;
340355 case kTfLiteAllocationStrategyNew :
341356 // Special case for variant objects. They are allocated using new/delete
342357 // but require using the `CloneTo` function.
343358 if (src.allocation_type == kTfLiteVariantObject ) {
344- dst.data .data = reinterpret_cast < const VariantData*>(src. data . data )
345- ->CloneTo (nullptr );
359+ dst.data .data =
360+ static_cast < const VariantData*>(src. data . data ) ->CloneTo (nullptr );
346361 } else {
347- dst.data .data = new char [src.bytes ];
362+ dst.data .data = new (std::nothrow) char [src.bytes ];
363+ if (src.bytes > 0 && !dst.data .data ) return TfLiteTensor ();
348364 std::memcpy (dst.data .data , src.data .data , src.bytes );
349365 }
350366 break ;
@@ -394,13 +410,21 @@ TfLiteStatus TfLiteTensorCopy(const TfLiteTensor* src, TfLiteTensor* dst) {
394410 }
395411 auto * dst_vd = static_cast <VariantData*>(dst->data .data );
396412 auto * src_vd = static_cast <VariantData*>(src->data .data );
413+ if (!src_vd) return kTfLiteError ;
397414
398415 // `CloneTo` will handle the case when `dst_vd` is nullptr, so it is safe
399416 // to `CloneTo` something which was "freed". Also, returning from `CloneTo`
400417 // will implicitly cast to `VariantData`; don't need static cast here.
401418 dst->data .data = src_vd->CloneTo (dst_vd);
402419 } else {
403- memcpy (dst->data .raw , src->data .raw , src->bytes );
420+ if (dst->allocation_type == kTfLiteVariantObject ) {
421+ TfLiteTensorDataFree (dst);
422+ dst->allocation_type = src->allocation_type ;
423+ }
424+ if (src->bytes > 0 ) {
425+ if (!dst->data .raw || !src->data .raw ) return kTfLiteError ;
426+ memcpy (dst->data .raw , src->data .raw , src->bytes );
427+ }
404428 }
405429 dst->buffer_handle = src->buffer_handle ;
406430 dst->data_is_stale = src->data_is_stale ;
0 commit comments