From 9df2defa295e1a3b315ed2a88791db51ff1f53e7 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Tue, 4 Aug 2015 11:26:48 +0100 Subject: Consume unknown fields when parsing. This is expected to be the cause of the conformance test failures. Generated code in next commit. --- .../Google.Protobuf.Test/GeneratedMessageTest.cs | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'csharp/src/Google.Protobuf.Test') diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs index 2b6265c1..1ef3d753 100644 --- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs +++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs @@ -36,6 +36,8 @@ using Google.Protobuf.TestProtos; using NUnit.Framework; using System.Collections; using System.Collections.Generic; +using System.Linq; +using Google.Protobuf.WellKnownTypes; namespace Google.Protobuf { @@ -590,5 +592,32 @@ namespace Google.Protobuf Assert.AreEqual(message, message2); Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase); } + + [Test] + public void IgnoreUnknownFields_RealDataStillRead() + { + var message = SampleMessages.CreateFullTestAllTypes(); + var stream = new MemoryStream(); + var output = new CodedOutputStream(stream); + var unusedFieldNumber = 23456; + Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber)); + output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited); + output.WriteString("ignore me"); + message.WriteTo(output); + output.Flush(); + + stream.Position = 0; + var parsed = TestAllTypes.Parser.ParseFrom(stream); + Assert.AreEqual(message, parsed); + } + + [Test] + public void IgnoreUnknownFields_AllTypes() + { + // Simple way of ensuring we can skip all kinds of fields. + var data = SampleMessages.CreateFullTestAllTypes().ToByteArray(); + var empty = Empty.Parser.ParseFrom(data); + Assert.AreEqual(new Empty(), empty); + } } } -- cgit v1.2.3 From fe355b26ec4646f79b6374a81050a992c9f34565 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Tue, 4 Aug 2015 11:26:58 +0100 Subject: Generated code changes for previous commit. --- csharp/src/AddressBook/Addressbook.cs | 3 ++ .../src/Google.Protobuf.Conformance/Conformance.cs | 5 ++++ .../TestProtos/MapUnittestProto3.cs | 7 +++++ .../TestProtos/UnittestImportProto3.cs | 1 + .../TestProtos/UnittestImportPublicProto3.cs | 1 + .../TestProtos/UnittestIssues.cs | 10 +++++++ .../TestProtos/UnittestProto3.cs | 35 ++++++++++++++++++++++ .../TestProtos/UnittestWellKnownTypes.cs | 4 +++ .../Reflection/DescriptorProtoFile.cs | 22 ++++++++++++++ csharp/src/Google.Protobuf/WellKnownTypes/Any.cs | 1 + csharp/src/Google.Protobuf/WellKnownTypes/Api.cs | 2 ++ .../src/Google.Protobuf/WellKnownTypes/Duration.cs | 1 + csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs | 1 + .../Google.Protobuf/WellKnownTypes/FieldMask.cs | 1 + .../WellKnownTypes/SourceContext.cs | 1 + .../src/Google.Protobuf/WellKnownTypes/Struct.cs | 3 ++ .../Google.Protobuf/WellKnownTypes/Timestamp.cs | 1 + csharp/src/Google.Protobuf/WellKnownTypes/Type.cs | 5 ++++ .../src/Google.Protobuf/WellKnownTypes/Wrappers.cs | 9 ++++++ 19 files changed, 113 insertions(+) (limited to 'csharp/src/Google.Protobuf.Test') diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs index 25752e20..571478f6 100644 --- a/csharp/src/AddressBook/Addressbook.cs +++ b/csharp/src/AddressBook/Addressbook.cs @@ -194,6 +194,7 @@ namespace Google.Protobuf.Examples.AddressBook { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -341,6 +342,7 @@ namespace Google.Protobuf.Examples.AddressBook { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Number = input.ReadString(); @@ -448,6 +450,7 @@ namespace Google.Protobuf.Examples.AddressBook { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { people_.AddEntriesFrom(input, _repeated_people_codec); diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs index 187eea9d..db0c1225 100644 --- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs +++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs @@ -326,6 +326,7 @@ namespace Conformance { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { ProtobufPayload = input.ReadBytes(); @@ -563,6 +564,7 @@ namespace Conformance { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { ParseError = input.ReadString(); @@ -1836,6 +1838,7 @@ namespace Conformance { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { OptionalInt32 = input.ReadInt32(); @@ -2264,6 +2267,7 @@ namespace Conformance { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { A = input.ReadInt32(); @@ -2382,6 +2386,7 @@ namespace Conformance { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { C = input.ReadInt32(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs index aac30ceb..db28213c 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs @@ -481,6 +481,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec); @@ -654,6 +655,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { if (testMap_ == null) { @@ -755,6 +757,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { mapInt32Message_.AddEntriesFrom(input, _map_mapInt32Message_codec); @@ -867,6 +870,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { map1_.AddEntriesFrom(input, _map_map1_codec); @@ -1165,6 +1169,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec); @@ -1319,6 +1324,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { type_.AddEntriesFrom(input, _map_type_codec); @@ -1427,6 +1433,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { entry_.AddEntriesFrom(input, _map_entry_codec); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs index fae10957..ae6e3a3f 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs @@ -144,6 +144,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { D = input.ReadInt32(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs index 17689f43..103ea8bb 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs @@ -130,6 +130,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { E = input.ReadInt32(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs index 8c0dc4e9..4e154456 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs @@ -147,6 +147,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -228,6 +229,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -309,6 +311,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -449,6 +452,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { value_ = (global::UnitTest.Issues.TestProtos.NegativeEnum) input.ReadEnum(); @@ -543,6 +547,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -740,6 +745,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { PrimitiveValue = input.ReadInt32(); @@ -871,6 +877,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Item = input.ReadInt32(); @@ -999,6 +1006,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Types_ = input.ReadInt32(); @@ -1088,6 +1096,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -1357,6 +1366,7 @@ namespace UnitTest.Issues.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { PlainString = input.ReadString(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs index e360ac15..9b4501c5 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs @@ -1216,6 +1216,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { SingleInt32 = input.ReadInt32(); @@ -1552,6 +1553,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Bb = input.ReadInt32(); @@ -1705,6 +1707,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { if (child_ == null) { @@ -1826,6 +1829,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { DeprecatedInt32 = input.ReadInt32(); @@ -1932,6 +1936,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { C = input.ReadInt32(); @@ -2016,6 +2021,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -2121,6 +2127,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { if (foreignNested_ == null) { @@ -2252,6 +2259,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { A = input.ReadInt32(); @@ -2387,6 +2395,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { if (a_ == null) { @@ -2503,6 +2512,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { if (bb_ == null) { @@ -2637,6 +2647,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { if (a_ == null) { @@ -2875,6 +2886,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { PrimitiveField = input.ReadInt32(); @@ -3083,6 +3095,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { MyInt = input.ReadInt64(); @@ -3227,6 +3240,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Bb = input.ReadInt32(); @@ -3342,6 +3356,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { sparseEnum_ = (global::Google.Protobuf.TestProtos.TestSparseEnum) input.ReadEnum(); @@ -3448,6 +3463,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Data = input.ReadString(); @@ -3546,6 +3562,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { data_.AddEntriesFrom(input, _repeated_data_codec); @@ -3652,6 +3669,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Data = input.ReadBytes(); @@ -3758,6 +3776,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Data = input.ReadBytes(); @@ -3864,6 +3883,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Data = input.ReadInt32(); @@ -3970,6 +3990,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Data = input.ReadUInt32(); @@ -4076,6 +4097,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Data = input.ReadInt64(); @@ -4182,6 +4204,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Data = input.ReadUInt64(); @@ -4288,6 +4311,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Data = input.ReadBool(); @@ -4467,6 +4491,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { FooInt = input.ReadInt32(); @@ -4760,6 +4785,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 722: case 720: { @@ -5106,6 +5132,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 722: case 720: { @@ -5340,6 +5367,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 98: case 101: { @@ -5472,6 +5500,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { A = input.ReadString(); @@ -5556,6 +5585,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -5636,6 +5666,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -5716,6 +5747,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -5796,6 +5828,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -5876,6 +5909,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } @@ -5956,6 +5990,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs index f18c5f1b..b05c80c1 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs @@ -684,6 +684,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { if (anyField_ == null) { @@ -1142,6 +1143,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { anyField_.AddEntriesFrom(input, _repeated_anyField_codec); @@ -1764,6 +1766,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { global::Google.Protobuf.WellKnownTypes.Any subBuilder = new global::Google.Protobuf.WellKnownTypes.Any(); @@ -2213,6 +2216,7 @@ namespace Google.Protobuf.TestProtos { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { anyField_.AddEntriesFrom(input, _map_anyField_codec); diff --git a/csharp/src/Google.Protobuf/Reflection/DescriptorProtoFile.cs b/csharp/src/Google.Protobuf/Reflection/DescriptorProtoFile.cs index e40472cb..a12e70f8 100644 --- a/csharp/src/Google.Protobuf/Reflection/DescriptorProtoFile.cs +++ b/csharp/src/Google.Protobuf/Reflection/DescriptorProtoFile.cs @@ -247,6 +247,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { file_.AddEntriesFrom(input, _repeated_file_codec); @@ -545,6 +546,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -840,6 +842,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -1008,6 +1011,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Start = input.ReadInt32(); @@ -1140,6 +1144,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Start = input.ReadInt32(); @@ -1434,6 +1439,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -1608,6 +1614,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -1753,6 +1760,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -1917,6 +1925,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -2073,6 +2082,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -2303,6 +2313,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -2732,6 +2743,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { JavaPackage = input.ReadString(); @@ -2986,6 +2998,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { MessageSetWireFormat = input.ReadBool(); @@ -3232,6 +3245,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { ctype_ = (global::Google.Protobuf.Reflection.FieldOptions.Types.CType) input.ReadEnum(); @@ -3416,6 +3430,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 16: { AllowAlias = input.ReadBool(); @@ -3544,6 +3559,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Deprecated = input.ReadBool(); @@ -3668,6 +3684,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 264: { Deprecated = input.ReadBool(); @@ -3792,6 +3809,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 264: { Deprecated = input.ReadBool(); @@ -4026,6 +4044,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 18: { name_.AddEntriesFrom(input, _repeated_name_codec); @@ -4179,6 +4198,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { NamePart_ = input.ReadString(); @@ -4286,6 +4306,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { location_.AddEntriesFrom(input, _repeated_location_codec); @@ -4457,6 +4478,7 @@ namespace Google.Protobuf.Reflection { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: case 8: { diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs index 93395871..4352c16a 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs @@ -155,6 +155,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { TypeUrl = input.ReadString(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs index 366bba21..a5d48166 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs @@ -218,6 +218,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -445,6 +446,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs index 26c8d2b6..1ca33dce 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs @@ -156,6 +156,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Seconds = input.ReadInt64(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs index e14992f4..0d948e38 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs @@ -111,6 +111,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; } } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs index 45ef9859..58dbc7fa 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs @@ -125,6 +125,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { paths_.AddEntriesFrom(input, _repeated_paths_codec); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs index 04fb6350..5566b5ce 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs @@ -134,6 +134,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { FileName = input.ReadString(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs index 15dd6dcd..72bd16d4 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs @@ -144,6 +144,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { fields_.AddEntriesFrom(input, _map_fields_codec); @@ -398,6 +399,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { kind_ = input.ReadEnum(); @@ -527,6 +529,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { values_.AddEntriesFrom(input, _repeated_values_codec); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs index 3c42068a..c3e5383e 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs @@ -156,6 +156,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Seconds = input.ReadInt64(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs index 64142934..862caf82 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs @@ -231,6 +231,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -502,6 +503,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { kind_ = (global::Google.Protobuf.WellKnownTypes.Field.Types.Kind) input.ReadEnum(); @@ -723,6 +725,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -880,6 +883,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); @@ -1019,6 +1023,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Name = input.ReadString(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs index c9dd6ea6..2b3814cc 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs @@ -143,6 +143,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 9: { Value = input.ReadDouble(); @@ -249,6 +250,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 13: { Value = input.ReadFloat(); @@ -355,6 +357,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Value = input.ReadInt64(); @@ -461,6 +464,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Value = input.ReadUInt64(); @@ -567,6 +571,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Value = input.ReadInt32(); @@ -673,6 +678,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Value = input.ReadUInt32(); @@ -779,6 +785,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 8: { Value = input.ReadBool(); @@ -885,6 +892,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Value = input.ReadString(); @@ -991,6 +999,7 @@ namespace Google.Protobuf.WellKnownTypes { if (pb::WireFormat.IsEndGroupTag(tag)) { return; } + input.ConsumeLastField(); break; case 10: { Value = input.ReadBytes(); -- cgit v1.2.3 From 15bf55e2251df4ad798a4f88b8514899c26e3dc3 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Tue, 4 Aug 2015 12:38:53 +0100 Subject: Validate that after reading a message, we've consumed as many bytes as we expected to. We should now have no conformance failures. --- conformance/failure_list_csharp.txt | 22 ---------------- .../Google.Protobuf.Test/GeneratedMessageTest.cs | 26 +++++++++++++------ csharp/src/Google.Protobuf/CodedInputStream.cs | 29 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 30 deletions(-) (limited to 'csharp/src/Google.Protobuf.Test') diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt index 34846589..e69de29b 100644 --- a/conformance/failure_list_csharp.txt +++ b/conformance/failure_list_csharp.txt @@ -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 diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs index 1ef3d753..6fdd1066 100644 --- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs +++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs @@ -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(() => TestAllTypes.Parser.ParseFrom(data)); + } } } diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs index fee31e3b..5da03b5c 100644 --- a/csharp/src/Google.Protobuf/CodedInputStream.cs +++ b/csharp/src/Google.Protobuf/CodedInputStream.cs @@ -54,13 +54,37 @@ namespace Google.Protobuf /// public sealed class CodedInputStream { + /// + /// Buffer of data read from the stream or provided at construction time. + /// private readonly byte[] buffer; + + /// + /// The number of valid bytes in the buffer. + /// private int bufferSize; + private int bufferSizeAfterLimit = 0; + /// + /// The position within the current buffer (i.e. the next byte to read) + /// private int bufferPos = 0; + + /// + /// The stream to read further input from, or null if the byte array buffer was provided + /// directly on construction, with no further data available. + /// private readonly Stream input; + + /// + /// The last tag we read. 0 indicates we've read to the end of the stream + /// (or haven't read anything yet). + /// private uint lastTag = 0; + /// + /// The next tag, used to store the value read by PeekTag. + /// 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); } -- cgit v1.2.3