mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
Fix messageset conformance for pure Python to match Py-C++ and Py-upb
MessageSet is a legacy affordance holdover from pre-proto2 days. Unlike the rest of Protobuf, it has first-wins instead of last-wins semantic in the case of duplicate ids or values within the same message set entry. No serializer would ever write such sequences, but the same hypothetical byte sequence being parsed differently by two implementations is undesirable. Note that other nonconformance fixes would commonly be held to breaking change releases to avoid any possible disruption of single-language users who may be relying on it as a load-bearing bug. However, the nature of this particular case is such that there is little reason to hold it back. PiperOrigin-RevId: 964043226
This commit is contained in:
parent
d0be1f2cb0
commit
02a9c9dec8
2 changed files with 17 additions and 9 deletions
|
|
@ -35,6 +35,3 @@ Recommended.Proto3.ProtobufInput.RejectInvalidUtf8.String.Singular
|
|||
# Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Oneof # Should have failed to parse, but didn't.
|
||||
# Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Repeated # Should have failed to parse, but didn't.
|
||||
# Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Singular # Should have failed to parse, but didn't.
|
||||
Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateDifferentTypeId.ProtobufOutput # Output was not equivalent to reference message
|
||||
Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateValue.ProtobufOutput # Output was not equivalent to reference message
|
||||
Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateValueOutOfOrder.ProtobufOutput # Output was not equivalent to reference message
|
||||
|
|
|
|||
|
|
@ -902,10 +902,15 @@ def MessageSetItemDecoder(descriptor):
|
|||
while 1:
|
||||
tag_bytes, pos = local_ReadTag(buffer, pos)
|
||||
if tag_bytes == type_id_tag_bytes:
|
||||
type_id, pos = local_DecodeVarint(buffer, pos)
|
||||
temp_type_id, pos = local_DecodeVarint(buffer, pos)
|
||||
if type_id == -1:
|
||||
type_id = temp_type_id
|
||||
elif tag_bytes == message_tag_bytes:
|
||||
size, message_start = local_DecodeVarint(buffer, pos)
|
||||
pos = message_end = message_start + size
|
||||
size, start = local_DecodeVarint(buffer, pos)
|
||||
if message_start == -1:
|
||||
message_start = start
|
||||
message_end = start + size
|
||||
pos = start + size
|
||||
elif tag_bytes == item_end_tag_bytes:
|
||||
break
|
||||
else:
|
||||
|
|
@ -967,15 +972,21 @@ def UnknownMessageSetItemDecoder():
|
|||
def DecodeUnknownItem(buffer):
|
||||
pos = 0
|
||||
end = len(buffer)
|
||||
type_id = -1
|
||||
message_start = -1
|
||||
message_end = -1
|
||||
while 1:
|
||||
tag_bytes, pos = ReadTag(buffer, pos)
|
||||
if tag_bytes == type_id_tag_bytes:
|
||||
type_id, pos = _DecodeVarint(buffer, pos)
|
||||
temp_type_id, pos = _DecodeVarint(buffer, pos)
|
||||
if type_id == -1:
|
||||
type_id = temp_type_id
|
||||
elif tag_bytes == message_tag_bytes:
|
||||
size, message_start = _DecodeVarint(buffer, pos)
|
||||
pos = message_end = message_start + size
|
||||
size, start = _DecodeVarint(buffer, pos)
|
||||
if message_start == -1:
|
||||
message_start = start
|
||||
message_end = start + size
|
||||
pos = start + size
|
||||
elif tag_bytes == item_end_tag_bytes:
|
||||
break
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue