77//
88
99#include < stdio.h>
10+ #include < limits>
1011
1112#include " TfliteUtils.hpp"
1213#include " liteOpConverter.hpp"
@@ -35,6 +36,11 @@ void Conv2DTflite::run(MNN::OpT* dstOp, const std::unique_ptr<tflite::OperatorT>
3536 const int inputSize = tfliteOp->inputs .size ();
3637 DCHECK (inputSize == 2 || inputSize == 3 ) << " tflite Conv2D input ERROR! " ;
3738 const auto & tfliteConvOption = tfliteOp->builtin_options .AsConv2DOptions ();
39+ if (nullptr == tfliteConvOption) {
40+ DLOG (ERROR ) << " CONV_2D operator carries no Conv2DOptions" ;
41+ dstOp->type = MNN ::OpType_MAX;
42+ return ;
43+ }
3844 const int inputIndex = tfliteOp->inputs [0 ];
3945 const int weightIndex = tfliteOp->inputs [1 ];
4046 const int outputIndex = tfliteOp->outputs [0 ];
@@ -60,12 +66,27 @@ void Conv2DTflite::run(MNN::OpT* dstOp, const std::unique_ptr<tflite::OperatorT>
6066 int group = 1 ;
6167 // co kh kw ci
6268 const auto & weightShape = weightTensor->shape ;
63- DCHECK (weightShape.size () == 4 ) << " Conv2D weight ERROR!" ;
69+ if (4 != weightShape.size ()) {
70+ DLOG (ERROR ) << " CONV_2D weight shape is not 4-D" ;
71+ dstOp->type = MNN ::OpType_MAX;
72+ return ;
73+ }
6474 const int co = weightShape[0 ];
6575 const int kh = weightShape[1 ];
6676 const int kw = weightShape[2 ];
6777 const int ci = weightShape[3 ];
68- const int weightSize = co * kh * kw * ci;
78+ if (co <= 0 || kh <= 0 || kw <= 0 || ci <= 0 ) {
79+ DLOG (ERROR ) << " CONV_2D weight shape contains non-positive dimension" ;
80+ dstOp->type = MNN ::OpType_MAX;
81+ return ;
82+ }
83+ const int64_t weightSize64 = (int64_t )co * kh * kw * ci;
84+ if (weightSize64 <= 0 || weightSize64 > std::numeric_limits<int >::max ()) {
85+ DLOG (ERROR ) << " CONV_2D weight size overflow: " << co << " x" << kh << " x" << kw << " x" << ci;
86+ dstOp->type = MNN ::OpType_MAX;
87+ return ;
88+ }
89+ const int weightSize = (int )weightSize64;
6990 if (inputShape.size () == 4 && inputShape[3 ] > ci) {
7091 group = inputShape[3 ] / ci;
7192 }
@@ -160,11 +181,14 @@ void Conv2DTflite::run(MNN::OpT* dstOp, const std::unique_ptr<tflite::OperatorT>
160181 conv2dParamQuan->biasQuantizedParam = std::unique_ptr<MNN ::QuantizedParamT>(new MNN ::QuantizedParamT);
161182 conv2dParamQuan->biasQuantizedParam ->zeroPoint = biasTensor->quantization ->zero_point [0 ];
162183 conv2dParamQuan->biasQuantizedParam ->scale = biasTensor->quantization ->scale [0 ];
163- DCHECK (biasData.size () / 4 == co) << " Bias Data ERROR" ;
164- auto biasDataPtr = biasData.data ();
165- const int32_t * realBiasDataPtr = (int32_t *)biasDataPtr;
166- std::vector<int32_t > biasInt32Vec (realBiasDataPtr, realBiasDataPtr + co);
167- conv2dParamQuan->bias = biasInt32Vec;
184+ if (biasData.size () >= sizeof (int32_t ) * co) {
185+ auto biasDataPtr = biasData.data ();
186+ const int32_t * realBiasDataPtr = (int32_t *)biasDataPtr;
187+ std::vector<int32_t > biasInt32Vec (realBiasDataPtr, realBiasDataPtr + co);
188+ conv2dParamQuan->bias = biasInt32Vec;
189+ } else {
190+ DLOG (ERROR ) << " CONV_2D bias buffer is too small, ignore bias" ;
191+ }
168192 }
169193
170194 conv2dParamQuan->activationType = (MNN ::FusedActivation)tfliteConvOption->fused_activation_function ;
@@ -255,10 +279,15 @@ void Conv2DTflite::run(MNN::OpT* dstOp, const std::unique_ptr<tflite::OperatorT>
255279 convolution2DQuant->bias .resize (co);
256280 if (inputSize == 3 ) {
257281 const auto & biasTensor = tfliteTensors[tfliteOp->inputs [2 ]];
258- auto bias = reinterpret_cast <const int *>(tfliteModelBuffer[biasTensor->buffer ]->data .data ());
259- // int to float
260- for (int i = 0 ; i < co; i++) {
261- convolution2DQuant->bias [i] = bias[i] * (scaleIn * alpha[i]);
282+ const auto & biasRaw = tfliteModelBuffer[biasTensor->buffer ]->data ;
283+ auto bias = reinterpret_cast <const int *>(biasRaw.data ());
284+ if (biasRaw.size () >= sizeof (int ) * co) {
285+ // int to float
286+ for (int i = 0 ; i < co; i++) {
287+ convolution2DQuant->bias [i] = bias[i] * (scaleIn * alpha[i]);
288+ }
289+ } else {
290+ DLOG (ERROR ) << " CONV_2D bias buffer is too small, ignore bias" ;
262291 }
263292 }
264293 dstOp->main .value = convolution2DQuant.release ();
@@ -323,8 +352,12 @@ void Conv2DTflite::run(MNN::OpT* dstOp, const std::unique_ptr<tflite::OperatorT>
323352 std::vector<float > biasData (co, 0 .0f );
324353 if (inputSize == 3 ) {
325354 const auto & biasTensor = tfliteTensors[tfliteOp->inputs [2 ]];
326- auto biasDataPtr = reinterpret_cast <const float *>(tfliteModelBuffer[biasTensor->buffer ]->data .data ());
327- ::memcpy (biasData.data(), biasDataPtr, sizeof(float ) * co);
355+ const auto & biasRaw = tfliteModelBuffer[biasTensor->buffer ]->data ;
356+ if (biasRaw.data () != nullptr && biasRaw.size () >= sizeof (float ) * co) {
357+ ::memcpy (biasData.data(), biasRaw.data(), sizeof(float ) * co);
358+ } else {
359+ DLOG (ERROR ) << " CONV_2D bias buffer is too small, ignore bias" ;
360+ }
328361 }
329362 convolution2DFloat->bias = biasData;
330363 dstOp->main .value = convolution2DFloat.release ();
@@ -365,32 +398,58 @@ void TransposeConvTflite::run(MNN::OpT *dstOp, const std::unique_ptr<tflite::Ope
365398 }
366399 */
367400 const auto & tfliteConvOption = tfliteOp->builtin_options .AsTransposeConvOptions ();
401+ if (nullptr == tfliteConvOption) {
402+ DLOG (ERROR ) << " TRANSPOSE_CONV operator carries no TransposeConvOptions" ;
403+ dstOp->type = MNN ::OpType_MAX;
404+ return ;
405+ }
368406 // weight index
369407 const int weightIndex = tfliteOp->inputs [1 ];
370408 const auto & weightTensor = tfliteTensors[weightIndex];
371409 // co kh kw ci
372410 const auto & weightShape = weightTensor->shape ;
373- DCHECK (weightShape.size () == 4 ) << " Conv2D weight ERROR!" ;
411+ if (4 != weightShape.size ()) {
412+ DLOG (ERROR ) << " TRANSPOSE_CONV weight shape is not 4-D" ;
413+ dstOp->type = MNN ::OpType_MAX;
414+ return ;
415+ }
374416 const int co = weightShape[0 ];
375417 const int kh = weightShape[1 ];
376418 const int kw = weightShape[2 ];
377419 const int ci = weightShape[3 ];
378- const int weightSize = co * kh * kw * ci;
420+ if (co <= 0 || kh <= 0 || kw <= 0 || ci <= 0 ) {
421+ DLOG (ERROR ) << " TRANSPOSE_CONV weight shape contains non-positive dimension" ;
422+ dstOp->type = MNN ::OpType_MAX;
423+ return ;
424+ }
425+ const int64_t weightSize64 = (int64_t )co * kh * kw * ci;
426+ if (weightSize64 <= 0 || weightSize64 > std::numeric_limits<int >::max ()) {
427+ DLOG (ERROR ) << " TRANSPOSE_CONV weight size overflow: " << co << " x" << kh << " x" << kw << " x" << ci;
428+ dstOp->type = MNN ::OpType_MAX;
429+ return ;
430+ }
431+ const int weightSize = (int )weightSize64;
379432 {
380433 auto convolution2DFloat = new MNN ::Convolution2DT;
381434 // weight
382435 std::vector<float > weightData;
383436 weightData.resize (weightSize);
384437 auto originalWeightPtr = reinterpret_cast <const float *>(tfliteModelBuffer[weightTensor->buffer ]->data .data ());
385- convertDataFormatTflite (originalWeightPtr, weightData.data (), kh, kw, ci, co, true );
438+ if (!convertDataFormatTflite (originalWeightPtr, weightData.data (), kh, kw, ci, co, true )) {
439+ DLOG (ERROR ) << " TRANSPOSE_CONV weight data is invalid" ;
440+ dstOp->type = MNN ::OpType_MAX;
441+ return ;
442+ }
386443 convolution2DFloat->weight = weightData;
387444 // bias
388445 std::vector<float > biasData (co, 0 .0f );
389446 if (inputSize == 4 ) {
390447 const auto & biasTensor = tfliteTensors[tfliteOp->inputs [2 ]];
391- auto biasDataPtr = reinterpret_cast <const float *>(tfliteModelBuffer[biasTensor->buffer ]->data .data ());
392- if (biasDataPtr){
393- ::memcpy (biasData.data(), biasDataPtr, sizeof(float ) * co);
448+ const auto & biasRaw = tfliteModelBuffer[biasTensor->buffer ]->data ;
449+ if (biasRaw.data () != nullptr && biasRaw.size () >= sizeof (float ) * co) {
450+ ::memcpy (biasData.data(), biasRaw.data(), sizeof(float ) * co);
451+ } else {
452+ DLOG (ERROR ) << " TRANSPOSE_CONV bias buffer is too small, ignore bias" ;
394453 }
395454 }
396455 convolution2DFloat->bias = biasData;
@@ -440,11 +499,16 @@ void FullConnectedTflite::run(MNN::OpT* dstOp, const std::unique_ptr<tflite::Ope
440499 const std::vector<std::unique_ptr<tflite::TensorT>>& tfliteTensors,
441500 const std::vector<std::unique_ptr<tflite::BufferT>>& tfliteModelBuffer,
442501 const std::vector<std::unique_ptr<tflite::OperatorCodeT>>& tfliteOpSet, int quantizedModel) {
502+ const auto & option = tfliteOp->builtin_options .AsFullyConnectedOptions ();
503+ if (nullptr == option) {
504+ DLOG (ERROR ) << " FULLY_CONNECTED operator carries no FullyConnectedOptions" ;
505+ dstOp->type = MNN ::OpType_MAX;
506+ return ;
507+ }
443508 dstOp->main .value = new MNN ::ExtraT;
444509 auto dstP = dstOp->main .AsExtra ();
445510 dstP->engine = " Tflite" ;
446511 dstP->type = " FULL_CONNECT" ;
447- const auto & option = tfliteOp->builtin_options .AsFullyConnectedOptions ();
448512 dstP->attr .resize (3 );
449513 dstP->attr [0 ].reset (new MNN ::AttributeT);
450514 dstP->attr [0 ]->key = " keep_num_dims" ;
0 commit comments