-
Notifications
You must be signed in to change notification settings - Fork 15.5k
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
C#: Wrong deserialization of Int32Value (from wrappers.proto) for negative values when segment boundary is crossed #8027
Comments
Can you provide an example of byte sequence that is parsed incorrectly? |
CC @JamesNK |
Value -1 encoded: 202 |
Fix - #8035 |
FTR quoting from the official docs: If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes long – it is, effectively, treated like a very large unsigned integer. |
Note that this bug only affects parsing of the Int32Value type from wrappers.proto:
|
What version of protobuf and what language are you using?
Version: v3.13.0
Language: C#
What operating system (Linux, Windows, ...) and version?
Reproducible on any version
What runtime / compiler are you using (e.g., python version or gcc version)
.NET Core
What did you do?
There is a problem with the deserialization of Int32 field when it contains a negative value. This happens only on very specific circumstances - when the field is serialized across the buffer (span) boundaries (when it starts at the and of one span and continues at the beginning of the next span). Deserialization thinks that the whole field fits to the first span, but this is not true and after deserialization, the buffer pointer is beyond the buffer size.
What did you expect to see
Successful deserialization of the message on the client
What did you see instead?
Exception:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Google.Protobuf.ParsingPrimitives.ReadRawByte(ReadOnlySpan
1& buffer, ParserInternalState& state) at Google.Protobuf.ParsingPrimitives.ParseRawVarint32SlowPath(ReadOnlySpan
1& buffer, ParserInternalState& state)at Google.Protobuf.ParsingPrimitivesWrappers.ReadUInt32WrapperSlow(ReadOnlySpan
1& buffer, ParserInternalState& state) at Google.Protobuf.ParsingPrimitivesWrappers.ReadInt32Wrapper(ReadOnlySpan
1& buffer, ParserInternalState& state)Details
This is the code for int32 serialization. Negative values are serialized as Varint64, it can be 11 bytes long.
But deserialization do not count with this. ReadUInt32Wrapper function has this condition there:
... which is not true for negative values.
The text was updated successfully, but these errors were encountered: