Skip to content

Commit

Permalink
Added a size overflow check for mini-table building
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 475172738
  • Loading branch information
haberman authored and copybara-github committed Sep 19, 2022
1 parent e55bfa2 commit ba511fd
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
8 changes: 7 additions & 1 deletion upb/mini_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,13 @@ size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) {
size_t size = upb_MtDecoder_SizeOfRep(rep, d->platform);
size_t align = upb_MtDecoder_AlignOfRep(rep, d->platform);
size_t ret = UPB_ALIGN_UP(d->table->size, align);
d->table->size = ret + size;
static const size_t max = UINT16_MAX;
size_t new_size = ret + size;
if (new_size > max) {
upb_MtDecoder_ErrorFormat(
d, "Message size exceeded maximum size of %zu bytes", max);
}
d->table->size = new_size;
return ret;
}

Expand Down
26 changes: 26 additions & 0 deletions upb/mini_table_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,32 @@ TEST_P(MiniTableTest, AllScalarTypesOneof) {
EXPECT_EQ(0, table->required_count);
}

TEST_P(MiniTableTest, SizeOverflow) {
upb::Arena arena;
upb::MtDataEncoder e;
// upb can only handle messages up to UINT16_MAX.
size_t max_double_fields = UINT16_MAX / (sizeof(double) + 1);

// A bit under max_double_fields is ok.
ASSERT_TRUE(e.StartMessage(0));
for (int i = 1; i < max_double_fields; i++) {
ASSERT_TRUE(e.PutField(kUpb_FieldType_Double, i, 0));
}
upb::Status status;
upb_MiniTable* table = upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table) << status.error_message();

// A bit over max_double_fields fails.
ASSERT_TRUE(e.StartMessage(0));
for (int i = 1; i < max_double_fields + 2; i++) {
ASSERT_TRUE(e.PutField(kUpb_FieldType_Double, i, 0));
}
upb_MiniTable* table2 = upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_EQ(nullptr, table2) << status.error_message();
}

INSTANTIATE_TEST_SUITE_P(Platforms, MiniTableTest,
testing::Values(kUpb_MiniTablePlatform_32Bit,
kUpb_MiniTablePlatform_64Bit));
Expand Down

0 comments on commit ba511fd

Please sign in to comment.