Skip to content

Commit

Permalink
fix unset mini table field presence bug
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 495373227
  • Loading branch information
ericsalo authored and copybara-github committed Dec 14, 2022
1 parent fa2481d commit 9ab09b4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
6 changes: 6 additions & 0 deletions upb/message/test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -596,4 +596,10 @@ TEST(MessageTest, MapField) {
// std::string("\035|", 2), 65536, 3);
// }
//
// // This test found a case where presence was unset for a mini table field.
// TEST(FuzzTest, DecodeEncodeArbitrarySchemaAndPayloadRegressionMsan) {
// DecodeEncodeArbitrarySchemaAndPayload({{"%-#^#"}, {}, "", {}}, std::string(),
// -1960166338, 16809991);
// }
//
// end:google_only
28 changes: 21 additions & 7 deletions upb/mini_table/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,22 +693,36 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
}

upb_MtDecoder_ParseMessage(d, data, len);
upb_MtDecoder_AssignHasbits(d->table);

if (UPB_UNLIKELY(d->table->field_count != 2)) {
upb_MtDecoder_ErrorFormat(d, "%hu fields in map", d->table->field_count);
UPB_UNREACHABLE();
}
if (UPB_UNLIKELY(d->table->fields[0].number != 1)) {
upb_MtDecoder_ErrorFormat(d, "field %d in map key",
d->table->fields[0].number);

const int num0 = d->table->fields[0].number;
if (UPB_UNLIKELY(num0 != 1)) {
upb_MtDecoder_ErrorFormat(d, "field %d in map key", num0);
UPB_UNREACHABLE();
}
if (UPB_UNLIKELY(d->table->fields[1].number != 2)) {
upb_MtDecoder_ErrorFormat(d, "field %d in map val",
d->table->fields[1].number);

const int num1 = d->table->fields[1].number;
if (UPB_UNLIKELY(num1 != 2)) {
upb_MtDecoder_ErrorFormat(d, "field %d in map val", num1);
UPB_UNREACHABLE();
}

upb_MtDecoder_AssignHasbits(d->table);
const int off0 = d->table->fields[0].offset;
if (UPB_UNLIKELY(off0 != kNoPresence && off0 != kHasbitPresence)) {
upb_MtDecoder_ErrorFormat(d, "bad offset %d in map key", off0);
UPB_UNREACHABLE();
}

const int off1 = d->table->fields[1].offset;
if (UPB_UNLIKELY(off1 != kNoPresence && off1 != kHasbitPresence)) {
upb_MtDecoder_ErrorFormat(d, "bad offset %d in map val", off1);
UPB_UNREACHABLE();
}

// Map entries have a pre-determined layout, regardless of types.
// NOTE: sync with mini_table/message_internal.h.
Expand Down

0 comments on commit 9ab09b4

Please sign in to comment.