Merge pull request #8035 from JamesNK/jamesnk/int32wrapper-blocksize
Fix parsing negative Int32Value that crosses segment boundary
This commit is contained in:
commit
012fe854ac
@ -343,6 +343,25 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadInt32Wrapper_VariableBlockSizes()
|
||||
{
|
||||
byte[] rawBytes = new byte[] { 202, 1, 11, 8, 254, 255, 255, 255, 255, 255, 255, 255, 255, 1 };
|
||||
|
||||
for (int blockSize = 1; blockSize <= rawBytes.Length; blockSize++)
|
||||
{
|
||||
ReadOnlySequence<byte> data = ReadOnlySequenceFactory.CreateWithContent(rawBytes, blockSize);
|
||||
AssertReadFromParseContext(data, (ref ParseContext ctx) =>
|
||||
{
|
||||
ctx.ReadTag();
|
||||
|
||||
var value = ParsingPrimitivesWrappers.ReadInt32Wrapper(ref ctx);
|
||||
|
||||
Assert.AreEqual(-2, value);
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadHugeBlob()
|
||||
{
|
||||
|
@ -87,6 +87,28 @@ namespace Google.Protobuf.WellKnownTypes
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NegativeSingleValues()
|
||||
{
|
||||
var message = new TestWellKnownTypes
|
||||
{
|
||||
FloatField = -12.5f,
|
||||
DoubleField = -12.25d,
|
||||
Int32Field = -1,
|
||||
Int64Field = -2
|
||||
};
|
||||
|
||||
MessageParsingHelpers.AssertWritingMessage(message);
|
||||
|
||||
MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed =>
|
||||
{
|
||||
Assert.AreEqual(-12.5f, parsed.FloatField);
|
||||
Assert.AreEqual(-12.25d, parsed.DoubleField);
|
||||
Assert.AreEqual(-1, parsed.Int32Field);
|
||||
Assert.AreEqual(-2L, parsed.Int64Field);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NonNullDefaultIsPreservedThroughSerialization()
|
||||
{
|
||||
|
@ -160,8 +160,11 @@ namespace Google.Protobuf
|
||||
|
||||
internal static uint? ReadUInt32Wrapper(ref ReadOnlySpan<byte> buffer, ref ParserInternalState state)
|
||||
{
|
||||
// length:1 + tag:1 + value:5(varint32-max) = 7 bytes
|
||||
if (state.bufferPos + 7 <= state.bufferSize)
|
||||
// field=1, type=varint = tag of 8
|
||||
const int expectedTag = 8;
|
||||
// length:1 + tag:1 + value:10(varint64-max) = 12 bytes
|
||||
// Value can be 64 bits for negative integers
|
||||
if (state.bufferPos + 12 <= state.bufferSize)
|
||||
{
|
||||
// The entire wrapper message is already contained in `buffer`.
|
||||
int pos0 = state.bufferPos;
|
||||
@ -177,8 +180,7 @@ namespace Google.Protobuf
|
||||
return ReadUInt32WrapperSlow(ref buffer, ref state);
|
||||
}
|
||||
int finalBufferPos = state.bufferPos + length;
|
||||
// field=1, type=varint = tag of 8
|
||||
if (buffer[state.bufferPos++] != 8)
|
||||
if (buffer[state.bufferPos++] != expectedTag)
|
||||
{
|
||||
state.bufferPos = pos0;
|
||||
return ReadUInt32WrapperSlow(ref buffer, ref state);
|
||||
|
Loading…
Reference in New Issue
Block a user