Skip to content
This repository was archived by the owner on Dec 9, 2025. It is now read-only.

Commit 9ab09b4

Browse files
ericsalocopybara-github
authored andcommitted
fix unset mini table field presence bug
PiperOrigin-RevId: 495373227
1 parent fa2481d commit 9ab09b4

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

upb/message/test.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,4 +596,10 @@ TEST(MessageTest, MapField) {
596596
// std::string("\035|", 2), 65536, 3);
597597
// }
598598
//
599+
// // This test found a case where presence was unset for a mini table field.
600+
// TEST(FuzzTest, DecodeEncodeArbitrarySchemaAndPayloadRegressionMsan) {
601+
// DecodeEncodeArbitrarySchemaAndPayload({{"%-#^#"}, {}, "", {}}, std::string(),
602+
// -1960166338, 16809991);
603+
// }
604+
//
599605
// end:google_only

upb/mini_table/decode.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -693,22 +693,36 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
693693
}
694694

695695
upb_MtDecoder_ParseMessage(d, data, len);
696+
upb_MtDecoder_AssignHasbits(d->table);
697+
696698
if (UPB_UNLIKELY(d->table->field_count != 2)) {
697699
upb_MtDecoder_ErrorFormat(d, "%hu fields in map", d->table->field_count);
698700
UPB_UNREACHABLE();
699701
}
700-
if (UPB_UNLIKELY(d->table->fields[0].number != 1)) {
701-
upb_MtDecoder_ErrorFormat(d, "field %d in map key",
702-
d->table->fields[0].number);
702+
703+
const int num0 = d->table->fields[0].number;
704+
if (UPB_UNLIKELY(num0 != 1)) {
705+
upb_MtDecoder_ErrorFormat(d, "field %d in map key", num0);
703706
UPB_UNREACHABLE();
704707
}
705-
if (UPB_UNLIKELY(d->table->fields[1].number != 2)) {
706-
upb_MtDecoder_ErrorFormat(d, "field %d in map val",
707-
d->table->fields[1].number);
708+
709+
const int num1 = d->table->fields[1].number;
710+
if (UPB_UNLIKELY(num1 != 2)) {
711+
upb_MtDecoder_ErrorFormat(d, "field %d in map val", num1);
708712
UPB_UNREACHABLE();
709713
}
710714

711-
upb_MtDecoder_AssignHasbits(d->table);
715+
const int off0 = d->table->fields[0].offset;
716+
if (UPB_UNLIKELY(off0 != kNoPresence && off0 != kHasbitPresence)) {
717+
upb_MtDecoder_ErrorFormat(d, "bad offset %d in map key", off0);
718+
UPB_UNREACHABLE();
719+
}
720+
721+
const int off1 = d->table->fields[1].offset;
722+
if (UPB_UNLIKELY(off1 != kNoPresence && off1 != kHasbitPresence)) {
723+
upb_MtDecoder_ErrorFormat(d, "bad offset %d in map val", off1);
724+
UPB_UNREACHABLE();
725+
}
712726

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

0 commit comments

Comments
 (0)