Validate that after reading a message, we've consumed as many bytes as we expected to.
We should now have no conformance failures.
This commit is contained in:
parent
fe355b26ec
commit
15bf55e225
@ -1,22 +0,0 @@
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.BOOL
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.BYTES
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.ENUM
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.INT32
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.INT64
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.SINT32
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.SINT64
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.STRING
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.UINT32
|
||||
ProtobufInput.PrematureEofBeforeUnknownValue.UINT64
|
||||
ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
|
||||
ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
|
||||
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
|
||||
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
|
@ -259,7 +259,7 @@ namespace Google.Protobuf
|
||||
output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
|
||||
var nestedMessage = new ForeignMessage { C = 20 };
|
||||
// Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
|
||||
output.WriteRawVarint32((uint)(nestedMessage.CalculateSize() + 3));
|
||||
output.WriteLength(2 + nestedMessage.CalculateSize());
|
||||
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteMessage(nestedMessage);
|
||||
output.Flush();
|
||||
@ -283,7 +283,7 @@ namespace Google.Protobuf
|
||||
|
||||
// Each field can be represented in a single byte, with a single byte tag.
|
||||
// Total message size: 6 bytes.
|
||||
output.WriteRawVarint32(6);
|
||||
output.WriteLength(6);
|
||||
output.WriteTag(1, WireFormat.WireType.Varint);
|
||||
output.WriteInt32(key);
|
||||
output.WriteTag(2, WireFormat.WireType.Varint);
|
||||
@ -309,7 +309,7 @@ namespace Google.Protobuf
|
||||
|
||||
// Each field can be represented in a single byte, with a single byte tag.
|
||||
// Total message size: 4 bytes.
|
||||
output.WriteRawVarint32(4);
|
||||
output.WriteLength(4);
|
||||
output.WriteTag(2, WireFormat.WireType.Varint);
|
||||
output.WriteInt32(value);
|
||||
output.WriteTag(1, WireFormat.WireType.Varint);
|
||||
@ -335,7 +335,7 @@ namespace Google.Protobuf
|
||||
var key1 = 10;
|
||||
var value1 = 20;
|
||||
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteRawVarint32(4);
|
||||
output.WriteLength(4);
|
||||
output.WriteTag(1, WireFormat.WireType.Varint);
|
||||
output.WriteInt32(key1);
|
||||
output.WriteTag(2, WireFormat.WireType.Varint);
|
||||
@ -345,7 +345,7 @@ namespace Google.Protobuf
|
||||
var key2 = "a";
|
||||
var value2 = "b";
|
||||
output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteRawVarint32(6); // 3 bytes per entry: tag, size, character
|
||||
output.WriteLength(6); // 3 bytes per entry: tag, size, character
|
||||
output.WriteTag(1, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteString(key2);
|
||||
output.WriteTag(2, WireFormat.WireType.LengthDelimited);
|
||||
@ -355,7 +355,7 @@ namespace Google.Protobuf
|
||||
var key3 = 15;
|
||||
var value3 = 25;
|
||||
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteRawVarint32(4);
|
||||
output.WriteLength(4);
|
||||
output.WriteTag(1, WireFormat.WireType.Varint);
|
||||
output.WriteInt32(key3);
|
||||
output.WriteTag(2, WireFormat.WireType.Varint);
|
||||
@ -383,7 +383,7 @@ namespace Google.Protobuf
|
||||
|
||||
// First entry
|
||||
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteRawVarint32(4);
|
||||
output.WriteLength(4);
|
||||
output.WriteTag(1, WireFormat.WireType.Varint);
|
||||
output.WriteInt32(key);
|
||||
output.WriteTag(2, WireFormat.WireType.Varint);
|
||||
@ -391,7 +391,7 @@ namespace Google.Protobuf
|
||||
|
||||
// Second entry - same key, different value
|
||||
output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
|
||||
output.WriteRawVarint32(4);
|
||||
output.WriteLength(4);
|
||||
output.WriteTag(1, WireFormat.WireType.Varint);
|
||||
output.WriteInt32(key);
|
||||
output.WriteTag(2, WireFormat.WireType.Varint);
|
||||
@ -619,5 +619,15 @@ namespace Google.Protobuf
|
||||
var empty = Empty.Parser.ParseFrom(data);
|
||||
Assert.AreEqual(new Empty(), empty);
|
||||
}
|
||||
|
||||
// This was originally seen as a conformance test failure.
|
||||
[Test]
|
||||
public void TruncatedMessageFieldThrows()
|
||||
{
|
||||
// 130, 3 is the message tag
|
||||
// 1 is the data length - but there's no data.
|
||||
var data = new byte[] { 130, 3, 1 };
|
||||
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,13 +54,37 @@ namespace Google.Protobuf
|
||||
/// </remarks>
|
||||
public sealed class CodedInputStream
|
||||
{
|
||||
/// <summary>
|
||||
/// Buffer of data read from the stream or provided at construction time.
|
||||
/// </summary>
|
||||
private readonly byte[] buffer;
|
||||
|
||||
/// <summary>
|
||||
/// The number of valid bytes in the buffer.
|
||||
/// </summary>
|
||||
private int bufferSize;
|
||||
|
||||
private int bufferSizeAfterLimit = 0;
|
||||
/// <summary>
|
||||
/// The position within the current buffer (i.e. the next byte to read)
|
||||
/// </summary>
|
||||
private int bufferPos = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The stream to read further input from, or null if the byte array buffer was provided
|
||||
/// directly on construction, with no further data available.
|
||||
/// </summary>
|
||||
private readonly Stream input;
|
||||
|
||||
/// <summary>
|
||||
/// The last tag we read. 0 indicates we've read to the end of the stream
|
||||
/// (or haven't read anything yet).
|
||||
/// </summary>
|
||||
private uint lastTag = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The next tag, used to store the value read by PeekTag.
|
||||
/// </summary>
|
||||
private uint nextTag = 0;
|
||||
private bool hasNextTag = false;
|
||||
|
||||
@ -456,6 +480,11 @@ namespace Google.Protobuf
|
||||
++recursionDepth;
|
||||
builder.MergeFrom(this);
|
||||
CheckLastTagWas(0);
|
||||
// Check that we've read exactly as much data as expected.
|
||||
if (!ReachedLimit)
|
||||
{
|
||||
throw InvalidProtocolBufferException.TruncatedMessage();
|
||||
}
|
||||
--recursionDepth;
|
||||
PopLimit(oldLimit);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user