diff --git a/upb/decode.c b/upb/decode.c index e55ee588bf..2456efa92d 100644 --- a/upb/decode.c +++ b/upb/decode.c @@ -421,7 +421,9 @@ static bool decode_checkenum_slow(upb_Decoder* d, const char* ptr, // For packed fields the tag could be arbitrarily far in the past, so we // just re-encode the tag and value here. uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; - upb_Decode_AddUnknownVarints(d, msg, tag, v); + upb_Message* unknown_msg = + field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg; + upb_Decode_AddUnknownVarints(d, unknown_msg, tag, v); return false; } @@ -1008,6 +1010,7 @@ static const char* decode_known(upb_Decoder* d, const char* ptr, upb_Message_Extension* ext = _upb_Message_GetOrCreateExtension(msg, ext_layout, &d->arena); if (UPB_UNLIKELY(!ext)) return decode_err(d, kUpb_DecodeStatus_OutOfMemory); + d->unknown_msg = msg; msg = &ext->data; subs = &ext->ext->sub; } @@ -1073,7 +1076,6 @@ static const char* decode_unknown(upb_Decoder* d, const char* ptr, d->unknown_msg = msg; ptr = decode_group(d, ptr, NULL, NULL, field_number); start = d->unknown; - d->unknown_msg = NULL; d->unknown = NULL; } if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) { @@ -1189,7 +1191,7 @@ upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg, state.extreg = extreg; state.limit_ptr = state.end; - state.unknown_msg = NULL; + state.unknown = NULL; state.depth = depth ? depth : 64; state.end_group = DECODE_NOGROUP; state.options = (uint16_t)options; diff --git a/upb/internal/decode.h b/upb/internal/decode.h index af244dbd19..99aa5ae824 100644 --- a/upb/internal/decode.h +++ b/upb/internal/decode.h @@ -46,8 +46,8 @@ typedef struct upb_Decoder { const char* end; /* Can read up to 16 bytes slop beyond this. */ const char* limit_ptr; /* = end + UPB_MIN(limit, 0) */ - upb_Message* unknown_msg; /* If non-NULL, add unknown data at buffer flip. */ - const char* unknown; /* Start of unknown data. */ + upb_Message* unknown_msg; /* Used for preserving unknown data. */ + const char* unknown; /* Start of unknown data, preserve at buffer flip. */ const upb_ExtensionRegistry* extreg; /* For looking up extensions during the parse. */ int limit; /* Submessage limit relative to end. */ @@ -120,7 +120,7 @@ const char* decode_isdonefallback_inl(upb_Decoder* d, const char* ptr, if (overrun < d->limit) { /* Need to copy remaining data into patch buffer. */ UPB_ASSERT(overrun < 16); - if (d->unknown_msg) { + if (d->unknown) { if (!_upb_Message_AddUnknown(d->unknown_msg, d->unknown, ptr - d->unknown, &d->arena)) { *status = kUpb_DecodeStatus_OutOfMemory; diff --git a/upb/mini_table.c b/upb/mini_table.c index 3caebdaa4e..1dfd00904e 100644 --- a/upb/mini_table.c +++ b/upb/mini_table.c @@ -963,7 +963,7 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, decoder.table->field_count = 0; decoder.table->ext = kUpb_ExtMode_NonExtendable; decoder.table->dense_below = 0; - decoder.table->table_mask = 0; + decoder.table->table_mask = -1; decoder.table->required_count = 0; upb_MtDecoder_ParseMessage(&decoder, data, len); @@ -986,7 +986,7 @@ upb_MiniTable* upb_MiniTable_BuildMessageSet(upb_MiniTablePlatform platform, ret->field_count = 0; ret->ext = kUpb_ExtMode_IsMessageSet; ret->dense_below = 0; - ret->table_mask = 0; + ret->table_mask = -1; ret->required_count = 0; return ret; } @@ -1027,7 +1027,7 @@ upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type, ret->field_count = 2; ret->ext = kUpb_ExtMode_NonExtendable | kUpb_ExtMode_IsMapEntry; ret->dense_below = 2; - ret->table_mask = 0; + ret->table_mask = -1; ret->required_count = 0; ret->subs = subs; ret->fields = fields; diff --git a/upb/msg_test.cc b/upb/msg_test.cc index 33b103a87f..696e1c1f4e 100644 --- a/upb/msg_test.cc +++ b/upb/msg_test.cc @@ -515,4 +515,14 @@ TEST(MessageTest, MapField) { // } // FUZZ_TEST(FuzzTest, DecodeEncodeArbitrarySchemaAndPayload); // +// TEST(FuzzTest, DecodeEncodeArbitrarySchemaAndPayloadRegression) { +// DecodeEncodeArbitrarySchemaAndPayload( +// {{"\256\354Rt\216\3271\234", "\243\243\267\207\336gV\366w"}, +// {"z"}, +// "}\212\304d\371\363\341\2329\325B\264\377?\215\223\201\201\226y\201%" +// "\321\363\255;", +// {}}, +// "\010", -724543908, -591643538); +// } +// // end:google_only