public void ReadStringGreaterThanCurrentLimit() { MemoryStream ms = new MemoryStream(); CodedOutputStream output = new CodedOutputStream(ms); uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); output.WriteRawVarint32(tag); output.WriteRawVarint32(4); output.WriteRawBytes(new byte[4]); // Pad with a few random bytes. output.Flush(); ms.Position = 0; CodedInputStream input = new CodedInputStream(ms.ToArray()); Assert.AreEqual(tag, input.ReadTag()); // Specify limit smaller than data length input.PushLimit(3); Assert.Throws <InvalidProtocolBufferException>(() => input.ReadString()); AssertReadFromParseContext(new ReadOnlySequence <byte>(ms.ToArray()), (ref ParseContext ctx) => { Assert.AreEqual(tag, ctx.ReadTag()); SegmentedBufferHelper.PushLimit(ref ctx.state, 3); try { ctx.ReadString(); Assert.Fail(); } catch (InvalidProtocolBufferException) { } }, true); }
internal static T Read <T>(CodedInputStream input, FieldCodec <T> codec) { int length = input.ReadLength(); int oldLimit = input.PushLimit(length); uint tag; T value = codec.DefaultValue; while (input.ReadTag(out tag)) { if (tag == 0) { throw InvalidProtocolBufferException.InvalidTag(); } if (tag == codec.Tag) { value = codec.Read(input); } if (WireFormat.IsEndGroupTag(tag)) { break; } } input.CheckLastTagWas(0); input.PopLimit(oldLimit); return(value); }
public void CodedInputStream_LimitReachedRightAfterTag() { MemoryStream ms = new MemoryStream(); var cos = new CodedOutputStream(ms); cos.WriteTag(11, WireFormat.WireType.Varint); Assert.AreEqual(1, cos.Position); cos.WriteString("some extra padding"); // ensure is currentLimit distinct from the end of the buffer. cos.Flush(); var cis = new CodedInputStream(ms.ToArray()); cis.PushLimit(1); // make sure we reach the limit right after reading the tag. // we still must read the tag correctly, even though the tag is at the very end of our limited input // (which is a corner case and will most likely result in an error when trying to read value of the field // described by this tag, but it would be a logical error not to read the tag that's actually present). // See https://github.com/protocolbuffers/protobuf/pull/7289 cis.AssertNextTag(WireFormat.MakeTag(11, WireFormat.WireType.Varint)); }
internal static T Read <T>(CodedInputStream input, FieldCodec <T> codec) { int length = input.ReadLength(); int oldLimit = input.PushLimit(length); uint tag; T value = codec.DefaultValue; while ((tag = input.ReadTag()) != 0) { if (tag == codec.Tag) { value = codec.Read(input); } else { input.SkipLastField(); } } input.CheckReadEndOfStreamTag(); input.PopLimit(oldLimit); return(value); }
public void TestCodedInputOutputPosition() { byte[] content = new byte[110]; for (int i = 0; i < content.Length; i++) { content[i] = (byte)i; } byte[] child = new byte[120]; { MemoryStream ms = new MemoryStream(child); CodedOutputStream cout = new CodedOutputStream(ms, 20); // Field 11: numeric value: 500 cout.WriteTag(11, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32(500); Assert.AreEqual(3, cout.Position); //Field 12: length delimited 120 bytes cout.WriteTag(12, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytes(ByteString.CopyFrom(content)); Assert.AreEqual(115, cout.Position); // Field 13: fixed numeric value: 501 cout.WriteTag(13, WireFormat.WireType.Fixed32); Assert.AreEqual(116, cout.Position); cout.WriteSFixed32(501); Assert.AreEqual(120, cout.Position); cout.Flush(); } byte[] bytes = new byte[130]; { CodedOutputStream cout = new CodedOutputStream(bytes); // Field 1: numeric value: 500 cout.WriteTag(1, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32(500); Assert.AreEqual(3, cout.Position); //Field 2: length delimited 120 bytes cout.WriteTag(2, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytes(ByteString.CopyFrom(child)); Assert.AreEqual(125, cout.Position); // Field 3: fixed numeric value: 500 cout.WriteTag(3, WireFormat.WireType.Fixed32); Assert.AreEqual(126, cout.Position); cout.WriteSFixed32(501); Assert.AreEqual(130, cout.Position); cout.Flush(); } // Now test Input stream: { CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0); Assert.AreEqual(0, cin.Position); // Field 1: uint tag = cin.ReadTag(); Assert.AreEqual(1, tag >> 3); Assert.AreEqual(1, cin.Position); Assert.AreEqual(500, cin.ReadInt32()); Assert.AreEqual(3, cin.Position); //Field 2: tag = cin.ReadTag(); Assert.AreEqual(2, tag >> 3); Assert.AreEqual(4, cin.Position); int childlen = cin.ReadLength(); Assert.AreEqual(120, childlen); Assert.AreEqual(5, cin.Position); int oldlimit = cin.PushLimit((int)childlen); Assert.AreEqual(5, cin.Position); // Now we are reading child message { // Field 11: numeric value: 500 tag = cin.ReadTag(); Assert.AreEqual(11, tag >> 3); Assert.AreEqual(6, cin.Position); Assert.AreEqual(500, cin.ReadInt32()); Assert.AreEqual(8, cin.Position); //Field 12: length delimited 120 bytes tag = cin.ReadTag(); Assert.AreEqual(12, tag >> 3); Assert.AreEqual(9, cin.Position); ByteString bstr = cin.ReadBytes(); Assert.AreEqual(110, bstr.Length); Assert.AreEqual((byte)109, bstr[109]); Assert.AreEqual(120, cin.Position); // Field 13: fixed numeric value: 501 tag = cin.ReadTag(); Assert.AreEqual(13, tag >> 3); // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit Assert.AreEqual(121, cin.Position); Assert.AreEqual(501, cin.ReadSFixed32()); Assert.AreEqual(125, cin.Position); Assert.IsTrue(cin.IsAtEnd); } cin.PopLimit(oldlimit); Assert.AreEqual(125, cin.Position); // Field 3: fixed numeric value: 501 tag = cin.ReadTag(); Assert.AreEqual(3, tag >> 3); Assert.AreEqual(126, cin.Position); Assert.AreEqual(501, cin.ReadSFixed32()); Assert.AreEqual(130, cin.Position); Assert.IsTrue(cin.IsAtEnd); } }
public void TestCodedInputOutputPosition() { byte[] content = new byte[110]; for (int i = 0; i < content.Length; i++) content[i] = (byte)i; byte[] child = new byte[120]; { MemoryStream ms = new MemoryStream(child); CodedOutputStream cout = new CodedOutputStream(ms, 20); // Field 11: numeric value: 500 cout.WriteTag(11, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32(500); Assert.AreEqual(3, cout.Position); //Field 12: length delimited 120 bytes cout.WriteTag(12, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytes(ByteString.CopyFrom(content)); Assert.AreEqual(115, cout.Position); // Field 13: fixed numeric value: 501 cout.WriteTag(13, WireFormat.WireType.Fixed32); Assert.AreEqual(116, cout.Position); cout.WriteSFixed32(501); Assert.AreEqual(120, cout.Position); cout.Flush(); } byte[] bytes = new byte[130]; { CodedOutputStream cout = new CodedOutputStream(bytes); // Field 1: numeric value: 500 cout.WriteTag(1, WireFormat.WireType.Varint); Assert.AreEqual(1, cout.Position); cout.WriteInt32(500); Assert.AreEqual(3, cout.Position); //Field 2: length delimited 120 bytes cout.WriteTag(2, WireFormat.WireType.LengthDelimited); Assert.AreEqual(4, cout.Position); cout.WriteBytes(ByteString.CopyFrom(child)); Assert.AreEqual(125, cout.Position); // Field 3: fixed numeric value: 500 cout.WriteTag(3, WireFormat.WireType.Fixed32); Assert.AreEqual(126, cout.Position); cout.WriteSFixed32(501); Assert.AreEqual(130, cout.Position); cout.Flush(); } // Now test Input stream: { CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0); Assert.AreEqual(0, cin.Position); // Field 1: uint tag = cin.ReadTag(); Assert.AreEqual(1, tag >> 3); Assert.AreEqual(1, cin.Position); Assert.AreEqual(500, cin.ReadInt32()); Assert.AreEqual(3, cin.Position); //Field 2: tag = cin.ReadTag(); Assert.AreEqual(2, tag >> 3); Assert.AreEqual(4, cin.Position); int childlen = cin.ReadLength(); Assert.AreEqual(120, childlen); Assert.AreEqual(5, cin.Position); int oldlimit = cin.PushLimit((int)childlen); Assert.AreEqual(5, cin.Position); // Now we are reading child message { // Field 11: numeric value: 500 tag = cin.ReadTag(); Assert.AreEqual(11, tag >> 3); Assert.AreEqual(6, cin.Position); Assert.AreEqual(500, cin.ReadInt32()); Assert.AreEqual(8, cin.Position); //Field 12: length delimited 120 bytes tag = cin.ReadTag(); Assert.AreEqual(12, tag >> 3); Assert.AreEqual(9, cin.Position); ByteString bstr = cin.ReadBytes(); Assert.AreEqual(110, bstr.Length); Assert.AreEqual((byte) 109, bstr[109]); Assert.AreEqual(120, cin.Position); // Field 13: fixed numeric value: 501 tag = cin.ReadTag(); Assert.AreEqual(13, tag >> 3); // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit Assert.AreEqual(121, cin.Position); Assert.AreEqual(501, cin.ReadSFixed32()); Assert.AreEqual(125, cin.Position); Assert.IsTrue(cin.IsAtEnd); } cin.PopLimit(oldlimit); Assert.AreEqual(125, cin.Position); // Field 3: fixed numeric value: 501 tag = cin.ReadTag(); Assert.AreEqual(3, tag >> 3); Assert.AreEqual(126, cin.Position); Assert.AreEqual(501, cin.ReadSFixed32()); Assert.AreEqual(130, cin.Position); Assert.IsTrue(cin.IsAtEnd); } }
internal static T Read <T>(CodedInputStream input, FieldCodec <T> codec) { int byteLimit = input.ReadLength(); T result; while (true) { IL_FA: uint arg_C8_0 = 1476935752u; while (true) { uint num; switch ((num = (arg_C8_0 ^ 2018772964u)) % 9u) { case 0u: input.SkipLastField(); arg_C8_0 = 1768391466u; continue; case 1u: { uint num2; arg_C8_0 = (((num2 = input.ReadTag()) == 0u) ? 789788880u : 1000495088u); continue; } case 3u: arg_C8_0 = (num * 422428889u ^ 15908708u); continue; case 4u: result = codec.Read(input); arg_C8_0 = (num * 2015424451u ^ 1456283564u); continue; case 5u: { uint num2; arg_C8_0 = ((num2 == codec.Tag) ? 627669222u : 345821031u); continue; } case 6u: { input.CheckReadEndOfStreamTag(); int oldLimit; input.PopLimit(oldLimit); arg_C8_0 = (num * 1368242210u ^ 1133084529u); continue; } case 7u: { int oldLimit = input.PushLimit(byteLimit); result = codec.DefaultValue; arg_C8_0 = (num * 2466023856u ^ 3651674u); continue; } case 8u: goto IL_FA; } return(result); } } return(result); }