-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proto: treat bad wire types as unknown fields #511
Conversation
Previously, an error was returned during unmarshal when a wiretype was encountered that did not match the expected type. In order to match the behavior of the C++ and Python implementations, we no longer return an error and instead store the bad wire fragment as an unknown field (or skip them if unknown field preservation is disabled). The generator still produces code that references ErrInternalBadWireType for unmarshal logic for oneof fields. However, the current proto package does not use the generated unmarshalers for oneofs, so their existence has no bearing on unmarshal semantics. Cleaning up the generator to stop producing these is future work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
A prior changed (see #511) allows Unmarshal to treat fields with unknown wire types with known tags as unknown fields. When do so, we must be careful not to set the required field bit. For example, suppose we have: message Foo { require fixed32 my_field = 1; } Then parsing a message with a field of type varint and tag 1 should not satisfy the required that Foo.my_field be set.
A prior changed (see #511) allows Unmarshal to treat fields with unknown wire types with known tags as unknown fields. When do so, we must be careful not to set the required field bit. For example, suppose we have: message Foo { require fixed32 my_field = 1; } Then parsing a message with a field of type varint and tag 1 should not satisfy the required that Foo.my_field be set.
A prior changed (see #511) allows Unmarshal to treat fields with unknown wire types with known tags as unknown fields. When do so, we must be careful not to set the required field bit. For example, suppose we have: message Foo { require fixed32 my_field = 1; } Then parsing a message with a field of type varint and tag 1 should not satisfy the required that Foo.my_field be set.
A prior changed (see #511) allows Unmarshal to treat fields with unknown wire types with known tags as unknown fields. When doing so, we must be careful not to set the required field bit. For example, suppose we have: message Foo { require fixed32 my_field = 1; } Then parsing a message with a field of type varint and tag 1 should not satisfy the required that Foo.my_field be set.
@dsnet just curious. Do you know why the original protobuf implementation treats incompatible wiretypes as unknowns? is it to help preserve compatibility between messages that might change wiretypes? |
This is the behavior of the C++ implementation, which has become the de-facto "standard" of "correct" behavior. The rationale for this property is not documented to my knowledge. |
thank you for the prompt response! |
Previously, an error was returned during unmarshal when a wiretype
was encountered that did not match the expected wiretype.
In order to match the behavior of the C++ and Python implementations,
we no longer return an error and instead store the bad wire fragment
as an unknown field (or skip them if unknown field preservation is disabled).
The generator still produces code that references ErrInternalBadWireType
for the unmarshal logic for oneof fields.
However, the current proto package does not use the generated unmarshalers
for oneofs, so their existence has no bearing on unmarshal semantics.
Cleaning up the generator to stop producing these is future work.