aboutsummaryrefslogtreecommitdiff
path: root/csharp/src/Google.Protobuf.Test
diff options
context:
space:
mode:
authorJan Tattermusch <jtattermusch@users.noreply.github.com>2015-11-05 18:41:05 -0800
committerJan Tattermusch <jtattermusch@users.noreply.github.com>2015-11-05 18:41:05 -0800
commitffe25c76eac55347d74bef508410f90f01f1db85 (patch)
treefa9638179b72bf9e763d1d76993f958546869301 /csharp/src/Google.Protobuf.Test
parent1470ced7ce6f8f5b42e0747ebbea1754db4a3310 (diff)
parent6fa17e759737e3225c6cc4ba830b921428c50781 (diff)
downloadprotobuf-ffe25c76eac55347d74bef508410f90f01f1db85.tar.gz
protobuf-ffe25c76eac55347d74bef508410f90f01f1db85.tar.bz2
protobuf-ffe25c76eac55347d74bef508410f90f01f1db85.zip
Merge pull request #941 from jskeet/recursion-limit
Add recursion limit handling to JSON parsing.
Diffstat (limited to 'csharp/src/Google.Protobuf.Test')
-rw-r--r--csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs4
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonParserTest.cs18
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs57
3 files changed, 77 insertions, 2 deletions
diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
index 54c44e47..6ae02112 100644
--- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
@@ -284,7 +284,7 @@ namespace Google.Protobuf
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
}
- private static TestRecursiveMessage MakeRecursiveMessage(int depth)
+ internal static TestRecursiveMessage MakeRecursiveMessage(int depth)
{
if (depth == 0)
{
@@ -296,7 +296,7 @@ namespace Google.Protobuf
}
}
- private static void AssertMessageDepth(TestRecursiveMessage message, int depth)
+ internal static void AssertMessageDepth(TestRecursiveMessage message, int depth)
{
if (depth == 0)
{
diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
index 29b3088c..c48b151d 100644
--- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
@@ -723,5 +723,23 @@ namespace Google.Protobuf
string json = "{} 10";
Assert.Throws<InvalidJsonException>(() => TestAllTypes.Parser.ParseJson(json));
}
+
+ /// <summary>
+ /// JSON equivalent to <see cref="CodedInputStreamTest.MaliciousRecursion"/>
+ /// </summary>
+ [Test]
+ public void MaliciousRecursion()
+ {
+ string data64 = CodedInputStreamTest.MakeRecursiveMessage(64).ToString();
+ string data65 = CodedInputStreamTest.MakeRecursiveMessage(65).ToString();
+
+ var parser64 = new JsonParser(new JsonParser.Settings(64));
+ CodedInputStreamTest.AssertMessageDepth(parser64.Parse<TestRecursiveMessage>(data64), 64);
+ Assert.Throws<InvalidProtocolBufferException>(() => parser64.Parse<TestRecursiveMessage>(data65));
+
+ var parser63 = new JsonParser(new JsonParser.Settings(63));
+ Assert.Throws<InvalidProtocolBufferException>(() => parser63.Parse<TestRecursiveMessage>(data64));
+
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
index 1b3c8e9f..a38efeed 100644
--- a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
@@ -82,6 +82,63 @@ namespace Google.Protobuf
}
[Test]
+ public void ObjectDepth()
+ {
+ string json = "{ \"foo\": { \"x\": 1, \"y\": [ 0 ] } }";
+ var tokenizer = new JsonTokenizer(new StringReader(json));
+ // If we had more tests like this, I'd introduce a helper method... but for one test, it's not worth it.
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.StartObject, tokenizer.Next());
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.Name("foo"), tokenizer.Next());
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.StartObject, tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.Name("x"), tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.Value(1), tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.Name("y"), tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.StartArray, tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth); // Depth hasn't changed in array
+ Assert.AreEqual(JsonToken.Value(0), tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.EndArray, tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.EndObject, tokenizer.Next());
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.EndObject, tokenizer.Next());
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ }
+
+ [Test]
+ public void ObjectDepth_WithPushBack()
+ {
+ string json = "{}";
+ var tokenizer = new JsonTokenizer(new StringReader(json));
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ var token = tokenizer.Next();
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ // When we push back a "start object", we should effectively be back to the previous depth.
+ tokenizer.PushBack(token);
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ // Read the same token again, and get back to depth 1
+ token = tokenizer.Next();
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+
+ // Now the same in reverse, with EndObject
+ token = tokenizer.Next();
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ tokenizer.PushBack(token);
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ tokenizer.Next();
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ }
+
+ [Test]
[TestCase("embedded tab\t")]
[TestCase("embedded CR\r")]
[TestCase("embedded LF\n")]