aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcsharptest <roger@csharptest.net>2011-06-11 12:22:17 -0500
committerrogerk <devnull@localhost>2011-06-11 12:22:17 -0500
commit3b70dd78ec6b3b348b51766ea728d8226c908fd6 (patch)
tree37660dd74701f61dbbff7fe23fd2b8b3679c654d
parent57fa7fddd7255acf5169462ae08b71b4c73b6b18 (diff)
downloadprotobuf-3b70dd78ec6b3b348b51766ea728d8226c908fd6.tar.gz
protobuf-3b70dd78ec6b3b348b51766ea728d8226c908fd6.tar.bz2
protobuf-3b70dd78ec6b3b348b51766ea728d8226c908fd6.zip
Added recursion limits to AbstractReader.cs
-rw-r--r--protos/extest/unittest_extras_xmltest.proto106
-rw-r--r--src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs312
-rw-r--r--src/ProtocolBuffers.Test/TestWriterFormatJson.cs9
-rw-r--r--src/ProtocolBuffers.Test/TestWriterFormatXml.cs8
-rw-r--r--src/ProtocolBuffers/Serialization/AbstractReader.cs31
-rw-r--r--src/ProtocolBuffers/Serialization/DictionaryWriter.cs14
-rw-r--r--src/ProtocolBuffers/Serialization/XmlFormatReader.cs6
7 files changed, 406 insertions, 80 deletions
diff --git a/protos/extest/unittest_extras_xmltest.proto b/protos/extest/unittest_extras_xmltest.proto
index 4a3b8810..331c6265 100644
--- a/protos/extest/unittest_extras_xmltest.proto
+++ b/protos/extest/unittest_extras_xmltest.proto
@@ -1,53 +1,57 @@
-// Additional options required for C# generation. File from copyright
-// line onwards is as per original distribution.
-import "google/protobuf/csharp_options.proto";
-option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
-option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestXmlSerializerTestProtoFile";
-
-package protobuf_unittest_extra;
-
-option optimize_for = SPEED;
-
-enum EnumOptions {
- ONE = 0;
- TWO = 1;
- THREE = 2;
-}
-
-message TestXmlChild
-{
- repeated EnumOptions options = 3;
- optional bytes binary = 4;
-}
-
-message TestXmlNoFields {
-}
-
-message TestXmlMessage {
-
- optional int64 number = 6;
- repeated int32 numbers = 2;
- optional string text = 3;
- repeated string textlines = 700;
- optional bool valid = 5;
-
- optional TestXmlChild child = 1;
- repeated group Children = 401
- {
- repeated EnumOptions options = 3;
+// Additional options required for C# generation. File from copyright
+// line onwards is as per original distribution.
+import "google/protobuf/csharp_options.proto";
+option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.TestProtos";
+option (google.protobuf.csharp_file_options).umbrella_classname = "UnitTestXmlSerializerTestProtoFile";
+
+package protobuf_unittest_extra;
+
+option optimize_for = SPEED;
+
+enum EnumOptions {
+ ONE = 0;
+ TWO = 1;
+ THREE = 2;
+}
+
+message TestXmlChild
+{
+ repeated EnumOptions options = 3;
+ optional bytes binary = 4;
+}
+
+message TestXmlNoFields {
+}
+
+message TestXmlRescursive {
+ optional TestXmlRescursive child = 1;
+}
+
+message TestXmlMessage {
+
+ optional int64 number = 6;
+ repeated int32 numbers = 2;
+ optional string text = 3;
+ repeated string textlines = 700;
+ optional bool valid = 5;
+
+ optional TestXmlChild child = 1;
+ repeated group Children = 401
+ {
+ repeated EnumOptions options = 3;
optional bytes binary = 4;
}
-
- extensions 100 to 199;
-}
-
-message TestXmlExtension {
- required int32 number = 1;
-}
-
-extend TestXmlMessage {
- optional EnumOptions extension_enum = 101;
- optional string extension_text = 102;
- repeated int32 extension_number = 103 [packed = true];
- optional TestXmlExtension extension_message = 199;
-}
+
+ extensions 100 to 199;
+}
+
+message TestXmlExtension {
+ required int32 number = 1;
+}
+
+extend TestXmlMessage {
+ optional EnumOptions extension_enum = 101;
+ optional string extension_text = 102;
+ repeated int32 extension_number = 103 [packed = true];
+ optional TestXmlExtension extension_message = 199;
+}
diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
index 441ea65a..c0507667 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
@@ -35,6 +35,8 @@ namespace Google.ProtocolBuffers.TestProtos {
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlChild, global::Google.ProtocolBuffers.TestProtos.TestXmlChild.Builder> internal__static_protobuf_unittest_extra_TestXmlChild__FieldAccessorTable;
internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestXmlNoFields__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlNoFields, global::Google.ProtocolBuffers.TestProtos.TestXmlNoFields.Builder> internal__static_protobuf_unittest_extra_TestXmlNoFields__FieldAccessorTable;
+ internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestXmlRescursive__Descriptor;
+ internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive, global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.Builder> internal__static_protobuf_unittest_extra_TestXmlRescursive__FieldAccessorTable;
internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestXmlMessage__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlMessage, global::Google.ProtocolBuffers.TestProtos.TestXmlMessage.Builder> internal__static_protobuf_unittest_extra_TestXmlMessage__FieldAccessorTable;
internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestXmlMessage_Children__Descriptor;
@@ -54,25 +56,27 @@ namespace Google.ProtocolBuffers.TestProtos {
"YnVmX3VuaXR0ZXN0X2V4dHJhGiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29w" +
"dGlvbnMucHJvdG8iVQoMVGVzdFhtbENoaWxkEjUKB29wdGlvbnMYAyADKA4y" +
"JC5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5FbnVtT3B0aW9ucxIOCgZiaW5h" +
- "cnkYBCABKAwiEQoPVGVzdFhtbE5vRmllbGRzIrcCCg5UZXN0WG1sTWVzc2Fn" +
- "ZRIOCgZudW1iZXIYBiABKAMSDwoHbnVtYmVycxgCIAMoBRIMCgR0ZXh0GAMg" +
- "ASgJEhIKCXRleHRsaW5lcxi8BSADKAkSDQoFdmFsaWQYBSABKAgSNAoFY2hp" +
- "bGQYASABKAsyJS5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0WG1sQ2hp" +
- "bGQSQwoIY2hpbGRyZW4YkQMgAygKMjAucHJvdG9idWZfdW5pdHRlc3RfZXh0" +
- "cmEuVGVzdFhtbE1lc3NhZ2UuQ2hpbGRyZW4aUQoIQ2hpbGRyZW4SNQoHb3B0" +
- "aW9ucxgDIAMoDjIkLnByb3RvYnVmX3VuaXR0ZXN0X2V4dHJhLkVudW1PcHRp" +
- "b25zEg4KBmJpbmFyeRgEIAEoDCoFCGQQyAEiIgoQVGVzdFhtbEV4dGVuc2lv" +
- "bhIOCgZudW1iZXIYASACKAUqKgoLRW51bU9wdGlvbnMSBwoDT05FEAASBwoD" +
- "VFdPEAESCQoFVEhSRUUQAjplCg5leHRlbnNpb25fZW51bRInLnByb3RvYnVm" +
- "X3VuaXR0ZXN0X2V4dHJhLlRlc3RYbWxNZXNzYWdlGGUgASgOMiQucHJvdG9i" +
- "dWZfdW5pdHRlc3RfZXh0cmEuRW51bU9wdGlvbnM6PwoOZXh0ZW5zaW9uX3Rl" +
- "eHQSJy5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0WG1sTWVzc2FnZRhm" +
- "IAEoCTpFChBleHRlbnNpb25fbnVtYmVyEicucHJvdG9idWZfdW5pdHRlc3Rf" +
- "ZXh0cmEuVGVzdFhtbE1lc3NhZ2UYZyADKAVCAhABOm4KEWV4dGVuc2lvbl9t" +
- "ZXNzYWdlEicucHJvdG9idWZfdW5pdHRlc3RfZXh0cmEuVGVzdFhtbE1lc3Nh" +
- "Z2UYxwEgASgLMikucHJvdG9idWZfdW5pdHRlc3RfZXh0cmEuVGVzdFhtbEV4" +
- "dGVuc2lvbkJMSAHCPkcKIUdvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMuVGVzdFBy" +
- "b3RvcxIiVW5pdFRlc3RYbWxTZXJpYWxpemVyVGVzdFByb3RvRmlsZQ==");
+ "cnkYBCABKAwiEQoPVGVzdFhtbE5vRmllbGRzIk4KEVRlc3RYbWxSZXNjdXJz" +
+ "aXZlEjkKBWNoaWxkGAEgASgLMioucHJvdG9idWZfdW5pdHRlc3RfZXh0cmEu" +
+ "VGVzdFhtbFJlc2N1cnNpdmUitwIKDlRlc3RYbWxNZXNzYWdlEg4KBm51bWJl" +
+ "chgGIAEoAxIPCgdudW1iZXJzGAIgAygFEgwKBHRleHQYAyABKAkSEgoJdGV4" +
+ "dGxpbmVzGLwFIAMoCRINCgV2YWxpZBgFIAEoCBI0CgVjaGlsZBgBIAEoCzIl" +
+ "LnByb3RvYnVmX3VuaXR0ZXN0X2V4dHJhLlRlc3RYbWxDaGlsZBJDCghjaGls" +
+ "ZHJlbhiRAyADKAoyMC5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0WG1s" +
+ "TWVzc2FnZS5DaGlsZHJlbhpRCghDaGlsZHJlbhI1CgdvcHRpb25zGAMgAygO" +
+ "MiQucHJvdG9idWZfdW5pdHRlc3RfZXh0cmEuRW51bU9wdGlvbnMSDgoGYmlu" +
+ "YXJ5GAQgASgMKgUIZBDIASIiChBUZXN0WG1sRXh0ZW5zaW9uEg4KBm51bWJl" +
+ "chgBIAIoBSoqCgtFbnVtT3B0aW9ucxIHCgNPTkUQABIHCgNUV08QARIJCgVU" +
+ "SFJFRRACOmUKDmV4dGVuc2lvbl9lbnVtEicucHJvdG9idWZfdW5pdHRlc3Rf" +
+ "ZXh0cmEuVGVzdFhtbE1lc3NhZ2UYZSABKA4yJC5wcm90b2J1Zl91bml0dGVz" +
+ "dF9leHRyYS5FbnVtT3B0aW9uczo/Cg5leHRlbnNpb25fdGV4dBInLnByb3Rv" +
+ "YnVmX3VuaXR0ZXN0X2V4dHJhLlRlc3RYbWxNZXNzYWdlGGYgASgJOkUKEGV4" +
+ "dGVuc2lvbl9udW1iZXISJy5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0" +
+ "WG1sTWVzc2FnZRhnIAMoBUICEAE6bgoRZXh0ZW5zaW9uX21lc3NhZ2USJy5w" +
+ "cm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0WG1sTWVzc2FnZRjHASABKAsy" +
+ "KS5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0WG1sRXh0ZW5zaW9uQkxI" +
+ "AcI+RwohR29vZ2xlLlByb3RvY29sQnVmZmVycy5UZXN0UHJvdG9zEiJVbml0" +
+ "VGVzdFhtbFNlcmlhbGl6ZXJUZXN0UHJvdG9GaWxl");
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_protobuf_unittest_extra_TestXmlChild__Descriptor = Descriptor.MessageTypes[0];
@@ -83,7 +87,11 @@ namespace Google.ProtocolBuffers.TestProtos {
internal__static_protobuf_unittest_extra_TestXmlNoFields__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlNoFields, global::Google.ProtocolBuffers.TestProtos.TestXmlNoFields.Builder>(internal__static_protobuf_unittest_extra_TestXmlNoFields__Descriptor,
new string[] { });
- internal__static_protobuf_unittest_extra_TestXmlMessage__Descriptor = Descriptor.MessageTypes[2];
+ internal__static_protobuf_unittest_extra_TestXmlRescursive__Descriptor = Descriptor.MessageTypes[2];
+ internal__static_protobuf_unittest_extra_TestXmlRescursive__FieldAccessorTable =
+ new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive, global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.Builder>(internal__static_protobuf_unittest_extra_TestXmlRescursive__Descriptor,
+ new string[] { "Child", });
+ internal__static_protobuf_unittest_extra_TestXmlMessage__Descriptor = Descriptor.MessageTypes[3];
internal__static_protobuf_unittest_extra_TestXmlMessage__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlMessage, global::Google.ProtocolBuffers.TestProtos.TestXmlMessage.Builder>(internal__static_protobuf_unittest_extra_TestXmlMessage__Descriptor,
new string[] { "Number", "Numbers", "Text", "Textlines", "Valid", "Child", "Children", });
@@ -91,7 +99,7 @@ namespace Google.ProtocolBuffers.TestProtos {
internal__static_protobuf_unittest_extra_TestXmlMessage_Children__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlMessage.Types.Children, global::Google.ProtocolBuffers.TestProtos.TestXmlMessage.Types.Children.Builder>(internal__static_protobuf_unittest_extra_TestXmlMessage_Children__Descriptor,
new string[] { "Options", "Binary", });
- internal__static_protobuf_unittest_extra_TestXmlExtension__Descriptor = Descriptor.MessageTypes[3];
+ internal__static_protobuf_unittest_extra_TestXmlExtension__Descriptor = Descriptor.MessageTypes[4];
internal__static_protobuf_unittest_extra_TestXmlExtension__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestXmlExtension, global::Google.ProtocolBuffers.TestProtos.TestXmlExtension.Builder>(internal__static_protobuf_unittest_extra_TestXmlExtension__Descriptor,
new string[] { "Number", });
@@ -634,6 +642,268 @@ namespace Google.ProtocolBuffers.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+ public sealed partial class TestXmlRescursive : pb::GeneratedMessage<TestXmlRescursive, TestXmlRescursive.Builder> {
+ private static readonly TestXmlRescursive defaultInstance = new Builder().BuildPartial();
+ private static readonly string[] _testXmlRescursiveFieldNames = new string[] { "child" };
+ private static readonly uint[] _testXmlRescursiveFieldTags = new uint[] { 10 };
+ public static TestXmlRescursive DefaultInstance {
+ get { return defaultInstance; }
+ }
+
+ public override TestXmlRescursive DefaultInstanceForType {
+ get { return defaultInstance; }
+ }
+
+ protected override TestXmlRescursive ThisMessage {
+ get { return this; }
+ }
+
+ public static pbd::MessageDescriptor Descriptor {
+ get { return global::Google.ProtocolBuffers.TestProtos.UnitTestXmlSerializerTestProtoFile.internal__static_protobuf_unittest_extra_TestXmlRescursive__Descriptor; }
+ }
+
+ protected override pb::FieldAccess.FieldAccessorTable<TestXmlRescursive, TestXmlRescursive.Builder> InternalFieldAccessors {
+ get { return global::Google.ProtocolBuffers.TestProtos.UnitTestXmlSerializerTestProtoFile.internal__static_protobuf_unittest_extra_TestXmlRescursive__FieldAccessorTable; }
+ }
+
+ public const int ChildFieldNumber = 1;
+ private bool hasChild;
+ private global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive child_ = global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.DefaultInstance;
+ public bool HasChild {
+ get { return hasChild; }
+ }
+ public global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive Child {
+ get { return child_; }
+ }
+
+ public override bool IsInitialized {
+ get {
+ return true;
+ }
+ }
+
+ public override void WriteTo(pb::ICodedOutputStream output) {
+ int size = SerializedSize;
+ string[] field_names = _testXmlRescursiveFieldNames;
+ if (hasChild) {
+ output.WriteMessage(1, field_names[0], Child);
+ }
+ UnknownFields.WriteTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public override int SerializedSize {
+ get {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (hasChild) {
+ size += pb::CodedOutputStream.ComputeMessageSize(1, Child);
+ }
+ size += UnknownFields.SerializedSize;
+ memoizedSerializedSize = size;
+ return size;
+ }
+ }
+
+ public static TestXmlRescursive ParseFrom(pb::ByteString data) {
+ return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+ }
+ public static TestXmlRescursive ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+ return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+ }
+ public static TestXmlRescursive ParseFrom(byte[] data) {
+ return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+ }
+ public static TestXmlRescursive ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+ return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+ }
+ public static TestXmlRescursive ParseFrom(global::System.IO.Stream input) {
+ return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+ }
+ public static TestXmlRescursive ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+ return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+ }
+ public static TestXmlRescursive ParseDelimitedFrom(global::System.IO.Stream input) {
+ return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+ }
+ public static TestXmlRescursive ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+ return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+ }
+ public static TestXmlRescursive ParseFrom(pb::ICodedInputStream input) {
+ return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+ }
+ public static TestXmlRescursive ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+ return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+ }
+ public static Builder CreateBuilder() { return new Builder(); }
+ public override Builder ToBuilder() { return CreateBuilder(this); }
+ public override Builder CreateBuilderForType() { return new Builder(); }
+ public static Builder CreateBuilder(TestXmlRescursive prototype) {
+ return (Builder) new Builder().MergeFrom(prototype);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+ public sealed partial class Builder : pb::GeneratedBuilder<TestXmlRescursive, Builder> {
+ protected override Builder ThisBuilder {
+ get { return this; }
+ }
+ public Builder() {}
+
+ TestXmlRescursive result = new TestXmlRescursive();
+
+ protected override TestXmlRescursive MessageBeingBuilt {
+ get { return result; }
+ }
+
+ public override Builder Clear() {
+ result = new TestXmlRescursive();
+ return this;
+ }
+
+ public override Builder Clone() {
+ return new Builder().MergeFrom(result);
+ }
+
+ public override pbd::MessageDescriptor DescriptorForType {
+ get { return global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.Descriptor; }
+ }
+
+ public override TestXmlRescursive DefaultInstanceForType {
+ get { return global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.DefaultInstance; }
+ }
+
+ public override TestXmlRescursive BuildPartial() {
+ if (result == null) {
+ throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+ }
+ TestXmlRescursive returnMe = result;
+ result = null;
+ return returnMe;
+ }
+
+ public override Builder MergeFrom(pb::IMessage other) {
+ if (other is TestXmlRescursive) {
+ return MergeFrom((TestXmlRescursive) other);
+ } else {
+ base.MergeFrom(other);
+ return this;
+ }
+ }
+
+ public override Builder MergeFrom(TestXmlRescursive other) {
+ if (other == global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.DefaultInstance) return this;
+ if (other.HasChild) {
+ MergeChild(other.Child);
+ }
+ this.MergeUnknownFields(other.UnknownFields);
+ return this;
+ }
+
+ public override Builder MergeFrom(pb::ICodedInputStream input) {
+ return MergeFrom(input, pb::ExtensionRegistry.Empty);
+ }
+
+ public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+ pb::UnknownFieldSet.Builder unknownFields = null;
+ uint tag;
+ string field_name;
+ while (input.ReadTag(out tag, out field_name)) {
+ if(tag == 0 && field_name != null) {
+ int field_ordinal = global::System.Array.BinarySearch(_testXmlRescursiveFieldNames, field_name, global::System.StringComparer.Ordinal);
+ if(field_ordinal >= 0)
+ tag = _testXmlRescursiveFieldTags[field_ordinal];
+ else {
+ if (unknownFields == null) {
+ unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+ }
+ ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+ continue;
+ }
+ }
+ switch (tag) {
+ case 0: {
+ throw pb::InvalidProtocolBufferException.InvalidTag();
+ }
+ default: {
+ if (pb::WireFormat.IsEndGroupTag(tag)) {
+ if (unknownFields != null) {
+ this.UnknownFields = unknownFields.Build();
+ }
+ return this;
+ }
+ if (unknownFields == null) {
+ unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+ }
+ ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+ break;
+ }
+ case 10: {
+ global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.CreateBuilder();
+ if (result.hasChild) {
+ subBuilder.MergeFrom(Child);
+ }
+ input.ReadMessage(subBuilder, extensionRegistry);
+ Child = subBuilder.BuildPartial();
+ break;
+ }
+ }
+ }
+
+ if (unknownFields != null) {
+ this.UnknownFields = unknownFields.Build();
+ }
+ return this;
+ }
+
+
+ public bool HasChild {
+ get { return result.hasChild; }
+ }
+ public global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive Child {
+ get { return result.Child; }
+ set { SetChild(value); }
+ }
+ public Builder SetChild(global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive value) {
+ pb::ThrowHelper.ThrowIfNull(value, "value");
+ result.hasChild = true;
+ result.child_ = value;
+ return this;
+ }
+ public Builder SetChild(global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.Builder builderForValue) {
+ pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+ result.hasChild = true;
+ result.child_ = builderForValue.Build();
+ return this;
+ }
+ public Builder MergeChild(global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive value) {
+ pb::ThrowHelper.ThrowIfNull(value, "value");
+ if (result.hasChild &&
+ result.child_ != global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.DefaultInstance) {
+ result.child_ = global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.CreateBuilder(result.child_).MergeFrom(value).BuildPartial();
+ } else {
+ result.child_ = value;
+ }
+ result.hasChild = true;
+ return this;
+ }
+ public Builder ClearChild() {
+ result.hasChild = false;
+ result.child_ = global::Google.ProtocolBuffers.TestProtos.TestXmlRescursive.DefaultInstance;
+ return this;
+ }
+ }
+ static TestXmlRescursive() {
+ object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestXmlSerializerTestProtoFile.Descriptor, null);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
public sealed partial class TestXmlMessage : pb::ExtendableMessage<TestXmlMessage, TestXmlMessage.Builder> {
private static readonly TestXmlMessage defaultInstance = new Builder().BuildPartial();
private static readonly string[] _testXmlMessageFieldNames = new string[] { "child", "children", "number", "numbers", "text", "textlines", "valid" };
diff --git a/src/ProtocolBuffers.Test/TestWriterFormatJson.cs b/src/ProtocolBuffers.Test/TestWriterFormatJson.cs
index 052d8f2b..fe6c22b4 100644
--- a/src/ProtocolBuffers.Test/TestWriterFormatJson.cs
+++ b/src/ProtocolBuffers.Test/TestWriterFormatJson.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Text;
using Google.ProtocolBuffers.Serialization;
using NUnit.Framework;
using Google.ProtocolBuffers.TestProtos;
@@ -336,6 +337,14 @@ namespace Google.ProtocolBuffers
Assert.AreEqual(3, ordinal);
Assert.AreEqual(3, builder.TextlinesCount);
}
+ [Test,ExpectedException(typeof(InvalidProtocolBufferException))]
+ public void TestRecursiveLimit()
+ {
+ StringBuilder sb = new StringBuilder(8192);
+ for (int i = 0; i < 80; i++)
+ sb.Append("{\"child\":");
+ TestXmlRescursive msg = TestXmlRescursive.ParseFromJson(sb.ToString());
+ }
[Test, ExpectedException(typeof(FormatException))]
public void FailWithEmptyText()
{
diff --git a/src/ProtocolBuffers.Test/TestWriterFormatXml.cs b/src/ProtocolBuffers.Test/TestWriterFormatXml.cs
index b5eb60bf..acad6f13 100644
--- a/src/ProtocolBuffers.Test/TestWriterFormatXml.cs
+++ b/src/ProtocolBuffers.Test/TestWriterFormatXml.cs
@@ -324,5 +324,13 @@ namespace Google.ProtocolBuffers
TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build();
Assert.AreEqual(message, copy);
}
+ [Test, ExpectedException(typeof(InvalidProtocolBufferException))]
+ public void TestRecursiveLimit()
+ {
+ StringBuilder sb = new StringBuilder(8192);
+ for (int i = 0; i < 80; i++)
+ sb.Append("<child>");
+ TestXmlRescursive msg = TestXmlRescursive.ParseFromXml("child", XmlReader.Create(new StringReader(sb.ToString())));
+ }
}
}
diff --git a/src/ProtocolBuffers/Serialization/AbstractReader.cs b/src/ProtocolBuffers/Serialization/AbstractReader.cs
index 8e4030e6..eb9baae1 100644
--- a/src/ProtocolBuffers/Serialization/AbstractReader.cs
+++ b/src/ProtocolBuffers/Serialization/AbstractReader.cs
@@ -12,6 +12,9 @@ namespace Google.ProtocolBuffers.Serialization
/// </summary>
public abstract class AbstractReader : ICodedInputStream
{
+ const int MaxDepth = CodedInputStream.DefaultRecursionLimit;
+ protected int _depth;
+
/// <summary>
/// Merges the contents of stream into the provided message builder
/// </summary>
@@ -330,13 +333,23 @@ namespace Google.ProtocolBuffers.Serialization
{ return Read(ref value); }
void ICodedInputStream.ReadGroup(int fieldNumber, IBuilderLite builder, ExtensionRegistry extensionRegistry)
- { ReadGroup(builder, extensionRegistry); }
+ {
+ if (_depth++ > MaxDepth)
+ throw InvalidProtocolBufferException.RecursionLimitExceeded();
+ ReadGroup(builder, extensionRegistry);
+ _depth--;
+ }
void ICodedInputStream.ReadUnknownGroup(int fieldNumber, IBuilderLite builder)
{ throw new NotSupportedException(); }
void ICodedInputStream.ReadMessage(IBuilderLite builder, ExtensionRegistry extensionRegistry)
- { ReadMessage(builder, extensionRegistry); }
+ {
+ if (_depth++ > MaxDepth)
+ throw InvalidProtocolBufferException.RecursionLimitExceeded();
+ ReadMessage(builder, extensionRegistry);
+ _depth--;
+ }
bool ICodedInputStream.ReadBytes(ref ByteString value)
{ return Read(ref value); }
@@ -439,10 +452,20 @@ namespace Google.ProtocolBuffers.Serialization
}
void ICodedInputStream.ReadMessageArray<T>(uint fieldTag, string fieldName, ICollection<T> list, T messageType, ExtensionRegistry registry)
- { ReadMessageArray(fieldName, list, messageType, registry); }
+ {
+ if (_depth++ > MaxDepth)
+ throw InvalidProtocolBufferException.RecursionLimitExceeded();
+ ReadMessageArray(fieldName, list, messageType, registry);
+ _depth--;
+ }
void ICodedInputStream.ReadGroupArray<T>(uint fieldTag, string fieldName, ICollection<T> list, T messageType, ExtensionRegistry registry)
- { ReadGroupArray(fieldName, list, messageType, registry); }
+ {
+ if (_depth++ > MaxDepth)
+ throw InvalidProtocolBufferException.RecursionLimitExceeded();
+ ReadGroupArray(fieldName, list, messageType, registry);
+ _depth--;
+ }
bool ICodedInputStream.ReadPrimitiveField(FieldType fieldType, ref object value)
{ return ReadField(fieldType, ref value); }
diff --git a/src/ProtocolBuffers/Serialization/DictionaryWriter.cs b/src/ProtocolBuffers/Serialization/DictionaryWriter.cs
index 596a9262..ccfa31f0 100644
--- a/src/ProtocolBuffers/Serialization/DictionaryWriter.cs
+++ b/src/ProtocolBuffers/Serialization/DictionaryWriter.cs
@@ -15,7 +15,7 @@ namespace Google.ProtocolBuffers.Serialization
/// Constructs a writer using a new dictionary
/// </summary>
public DictionaryWriter()
- : this(new Dictionary<string,object>())
+ : this(new Dictionary<string,object>(StringComparer.Ordinal))
{ }
/// <summary>
@@ -28,6 +28,14 @@ namespace Google.ProtocolBuffers.Serialization
}
/// <summary>
+ /// Creates the dictionary instance for a child message.
+ /// </summary>
+ protected virtual DictionaryWriter Create()
+ {
+ return new DictionaryWriter();
+ }
+
+ /// <summary>
/// Accesses the dictionary that is backing this writer
/// </summary>
public IDictionary<string, object> ToDictionary() { return _output; }
@@ -119,7 +127,7 @@ namespace Google.ProtocolBuffers.Serialization
/// </summary>
protected override void WriteMessageOrGroup(string field, IMessageLite message)
{
- DictionaryWriter writer = new DictionaryWriter();
+ DictionaryWriter writer = Create();
writer.WriteMessage(message);
_output[field] = writer.ToDictionary();
@@ -146,7 +154,7 @@ namespace Google.ProtocolBuffers.Serialization
case FieldType.Group:
case FieldType.Message:
{
- DictionaryWriter writer = new DictionaryWriter();
+ DictionaryWriter writer = Create();
writer.WriteMessage((IMessageLite)o);
objects.Add(writer.ToDictionary());
}
diff --git a/src/ProtocolBuffers/Serialization/XmlFormatReader.cs b/src/ProtocolBuffers/Serialization/XmlFormatReader.cs
index 241c554a..fcd83fb3 100644
--- a/src/ProtocolBuffers/Serialization/XmlFormatReader.cs
+++ b/src/ProtocolBuffers/Serialization/XmlFormatReader.cs
@@ -72,7 +72,11 @@ namespace Google.ProtocolBuffers.Serialization
private XmlFormatReader CloneWith(XmlReader rdr)
{
- return new XmlFormatReader(rdr).SetOptions(Options);
+ XmlFormatReader copy = new XmlFormatReader(rdr).SetOptions(Options);
+ copy._rootElementName = _rootElementName;
+ copy._depth = _depth;
+ return copy;
+
}
private void NextElement()
{