From 9bdc848832b6f6e27ea4389a72c566ec43329114 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Mon, 15 Feb 2016 11:58:01 +0000 Subject: Validate that end-group tags match their corresponding start-group tags This detects: - An end-group tag with the wrong field number (doesn't match the start-group field) - An end-group tag with no preceding start-group tag Fixes issue #688. --- .../Google.Protobuf.Test/CodedInputStreamTest.cs | 50 +++++++++++++++++++++- .../Google.Protobuf.Test/GeneratedMessageTest.cs | 7 ++- 2 files changed, 51 insertions(+), 6 deletions(-) (limited to 'csharp/src/Google.Protobuf.Test') diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs index 6ae02112..0e7cf04e 100644 --- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs +++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs @@ -469,6 +469,52 @@ namespace Google.Protobuf Assert.AreEqual("field 3", input.ReadString()); } + [Test] + public void SkipGroup_WrongEndGroupTag() + { + // Create an output stream with: + // Field 1: string "field 1" + // Start group 2 + // Field 3: fixed int32 + // End group 4 (should give an error) + var stream = new MemoryStream(); + var output = new CodedOutputStream(stream); + output.WriteTag(1, WireFormat.WireType.LengthDelimited); + output.WriteString("field 1"); + + // The outer group... + output.WriteTag(2, WireFormat.WireType.StartGroup); + output.WriteTag(3, WireFormat.WireType.Fixed32); + output.WriteFixed32(100); + output.WriteTag(4, WireFormat.WireType.EndGroup); + output.Flush(); + stream.Position = 0; + + // Now act like a generated client + var input = new CodedInputStream(stream); + Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag()); + Assert.AreEqual("field 1", input.ReadString()); + Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag()); + Assert.Throws(input.SkipLastField); + } + + [Test] + public void RogueEndGroupTag() + { + // If we have an end-group tag without a leading start-group tag, generated + // code will just call SkipLastField... so that should fail. + + var stream = new MemoryStream(); + var output = new CodedOutputStream(stream); + output.WriteTag(1, WireFormat.WireType.EndGroup); + output.Flush(); + stream.Position = 0; + + var input = new CodedInputStream(stream); + Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag()); + Assert.Throws(input.SkipLastField); + } + [Test] public void EndOfStreamReachedWhileSkippingGroup() { @@ -484,7 +530,7 @@ namespace Google.Protobuf // Now act like a generated client var input = new CodedInputStream(stream); input.ReadTag(); - Assert.Throws(() => input.SkipLastField()); + Assert.Throws(input.SkipLastField); } [Test] @@ -506,7 +552,7 @@ namespace Google.Protobuf // Now act like a generated client var input = new CodedInputStream(stream); Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag()); - Assert.Throws(() => input.SkipLastField()); + Assert.Throws(input.SkipLastField); } [Test] diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs index 14cc6d19..67069954 100644 --- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs +++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs @@ -679,21 +679,20 @@ namespace Google.Protobuf /// for details; we may want to change this. /// [Test] - public void ExtraEndGroupSkipped() + public void ExtraEndGroupThrows() { var message = SampleMessages.CreateFullTestAllTypes(); var stream = new MemoryStream(); var output = new CodedOutputStream(stream); - output.WriteTag(100, WireFormat.WireType.EndGroup); output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32); output.WriteFixed32(123); + output.WriteTag(100, WireFormat.WireType.EndGroup); output.Flush(); stream.Position = 0; - var parsed = TestAllTypes.Parser.ParseFrom(stream); - Assert.AreEqual(new TestAllTypes { SingleFixed32 = 123 }, parsed); + Assert.Throws(() => TestAllTypes.Parser.ParseFrom(stream)); } [Test] -- cgit v1.2.3