@@ -1384,4 +1384,122 @@ TF_LITE_MICRO_TEST(TestMultiSubgraphNumScratchAllocations) {
13841384 used_bytes + sizeof (tflite::ScratchBufferHandle) * 2 );
13851385}
13861386
1387+ // New tests validating invalid buffer index guards in tensor initialization
1388+ // and model allocation paths. These exercise issues #3077, #3076, #3075.
1389+
1390+ TF_LITE_MICRO_TEST (InitializeTfLiteTensorFromFlatbuffer_InvalidBufferIndexReturnsError) {
1391+ // Arena and allocator for temporary/persistent allocations used by init.
1392+ constexpr size_t arena_size = 1024 ;
1393+ uint8_t arena[arena_size];
1394+ tflite::SingleArenaBufferAllocator* simple_allocator =
1395+ tflite::SingleArenaBufferAllocator::Create (arena, arena_size);
1396+
1397+ // Build a flatbuffer Tensor that references a non-existent buffer index.
1398+ flatbuffers::FlatBufferBuilder builder;
1399+ const int32_t dims_data[] = {1 };
1400+ auto dims_vec = builder.CreateVector (dims_data, 1 );
1401+ // Use an invalid buffer index (>= buffers->size()).
1402+ const uint32_t kInvalidBufferIndex = 5 ;
1403+ auto name_str = builder.CreateString (" invalid_buffer_tensor" );
1404+ auto tensor_offset = tflite::CreateTensor (
1405+ builder, /* shape=*/ dims_vec, tflite::TensorType_INT32,
1406+ /* buffer=*/ kInvalidBufferIndex , /* name=*/ name_str,
1407+ /* quantization=*/ 0 , /* is_variable=*/ false , /* sparsity=*/ 0 );
1408+ builder.Finish (tensor_offset);
1409+ const tflite::Tensor* bad_tensor =
1410+ flatbuffers::GetRoot<tflite::Tensor>(builder.GetBufferPointer ());
1411+
1412+ // Create a buffers vector with a single empty buffer.
1413+ const flatbuffers::Vector<flatbuffers::Offset<tflite::Buffer>>* buffers =
1414+ tflite::testing::CreateFlatbufferBuffers ();
1415+
1416+ TfLiteTensor out_tensor;
1417+ // Expect kTfLiteError due to invalid buffer index.
1418+ TF_LITE_MICRO_EXPECT_EQ (
1419+ kTfLiteError ,
1420+ tflite::internal::InitializeTfLiteTensorFromFlatbuffer (
1421+ simple_allocator, simple_allocator, /* allocate_temp=*/ false ,
1422+ *bad_tensor, buffers, &out_tensor));
1423+
1424+ simple_allocator->~SingleArenaBufferAllocator ();
1425+ }
1426+
1427+ TF_LITE_MICRO_TEST (InitializeTfLiteEvalTensorFromFlatbuffer_InvalidBufferIndexReturnsError) {
1428+ // Build a flatbuffer Tensor that references a non-existent buffer index.
1429+ flatbuffers::FlatBufferBuilder builder;
1430+ const int32_t dims_data[] = {1 };
1431+ auto dims_vec = builder.CreateVector (dims_data, 1 );
1432+ const uint32_t kInvalidBufferIndex = 7 ;
1433+ auto name_str = builder.CreateString (" invalid_eval_buffer_tensor" );
1434+ auto tensor_offset = tflite::CreateTensor (
1435+ builder, /* shape=*/ dims_vec, tflite::TensorType_INT32,
1436+ /* buffer=*/ kInvalidBufferIndex , /* name=*/ name_str,
1437+ /* quantization=*/ 0 , /* is_variable=*/ false , /* sparsity=*/ 0 );
1438+ builder.Finish (tensor_offset);
1439+ const tflite::Tensor* bad_tensor =
1440+ flatbuffers::GetRoot<tflite::Tensor>(builder.GetBufferPointer ());
1441+
1442+ // Create a buffers vector with a single empty buffer.
1443+ const flatbuffers::Vector<flatbuffers::Offset<tflite::Buffer>>* buffers =
1444+ tflite::testing::CreateFlatbufferBuffers ();
1445+
1446+ TfLiteEvalTensor out_eval_tensor;
1447+ // Expect kTfLiteError due to invalid buffer index.
1448+ TF_LITE_MICRO_EXPECT_EQ (
1449+ kTfLiteError ,
1450+ tflite::internal::InitializeTfLiteEvalTensorFromFlatbuffer (
1451+ *bad_tensor, buffers, &out_eval_tensor));
1452+ }
1453+
1454+ TF_LITE_MICRO_TEST (StartModelAllocation_FailsWhenSubgraphHasTensorWithInvalidBufferIndex) {
1455+ // Build a minimal model with a single tensor that references an invalid
1456+ // buffer index. Make it an output tensor to mimic output-table invalid case
1457+ // (#3075), but the allocator will validate all tensors equally, so this also
1458+ // simulates intermediate cases (#3076).
1459+ flatbuffers::FlatBufferBuilder fbb;
1460+
1461+ // One empty buffer at index 0 in Model.buffers().
1462+ flatbuffers::Offset<tflite::Buffer> buffers_arr[1 ] = {tflite::CreateBuffer (fbb)};
1463+ auto buffers_fb = fbb.CreateVector (buffers_arr, 1 );
1464+
1465+ // Tensor with invalid buffer index.
1466+ const int32_t dims_data[] = {1 };
1467+ auto dims_vec = fbb.CreateVector (dims_data, 1 );
1468+ const uint32_t kInvalidBufferIndex = 3 ; // >= buffers_vec.size()
1469+ auto t_name = fbb.CreateString (" out_tensor_invalid_buf" );
1470+ auto tensor = tflite::CreateTensor (
1471+ fbb, dims_vec, tflite::TensorType_INT32, kInvalidBufferIndex , t_name,
1472+ /* quantization=*/ 0 , /* is_variable=*/ false , /* sparsity=*/ 0 );
1473+ auto tensors_vec = fbb.CreateVector (&tensor, 1 );
1474+
1475+ // Subgraph with the tensor as an output; no operators required.
1476+ const int32_t outputs_idx[] = {0 };
1477+ auto outputs = fbb.CreateVector (outputs_idx, 1 );
1478+ auto inputs = fbb.CreateVector <int32_t >({});
1479+ auto ops = fbb.CreateVector <flatbuffers::Offset<tflite::Operator>>({});
1480+ auto subgraph = tflite::CreateSubGraph (
1481+ fbb, tensors_vec, inputs, outputs, ops, fbb.CreateString (" sg0" ));
1482+ auto subgraphs = fbb.CreateVector (&subgraph, 1 );
1483+
1484+ // Minimal model (no operator codes needed as there are no operators).
1485+ auto model = tflite::CreateModel (
1486+ fbb, /* version=*/ TFLITE_SCHEMA_VERSION,
1487+ /* operator_codes=*/ 0 , subgraphs, fbb.CreateString (" invalid_buf_model" ),
1488+ buffers_fb);
1489+ tflite::FinishModelBuffer (fbb, model);
1490+ const tflite::Model* m = flatbuffers::GetRoot<tflite::Model>(fbb.GetBufferPointer ());
1491+
1492+ // Allocate an arena and create the allocator.
1493+ constexpr size_t arena_size = 2048 ;
1494+ uint8_t arena[arena_size];
1495+ tflite::MicroAllocator* allocator =
1496+ tflite::MicroAllocator::Create (arena, arena_size);
1497+ TF_LITE_MICRO_EXPECT (nullptr != allocator);
1498+
1499+ // StartModelAllocation should fail (return nullptr) because initializing
1500+ // any eval tensor with an invalid buffer index returns kTfLiteError.
1501+ tflite::SubgraphAllocations* subgraph_allocations = allocator->StartModelAllocation (m);
1502+ TF_LITE_MICRO_EXPECT (nullptr == subgraph_allocations);
1503+ }
1504+
13871505TF_LITE_MICRO_TESTS_END
0 commit comments