Skip to content

Commit

Permalink
Fix issues that are variants of those #1182 (#1184)
Browse files Browse the repository at this point in the history
* Catch excessive objects in json being parsed, even if following a comment.

* Include line info on excessive content for deserialisation.
  • Loading branch information
JonHanna authored and JamesNK committed Jan 18, 2017
1 parent 76600dc commit 8956d3c
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 10 deletions.
25 changes: 25 additions & 0 deletions Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,31 @@ public void Parse_NoComments()
Assert.AreEqual(3, (int)a[2]);
}

[Test]
public void Parse_ExcessiveContentJustComments()
{
string json = @"[1,2,3]/*comment*/
//Another comment.";

JArray a = JArray.Parse(json);

Assert.AreEqual(3, a.Count);
Assert.AreEqual(1, (int)a[0]);
Assert.AreEqual(2, (int)a[1]);
Assert.AreEqual(3, (int)a[2]);
}

[Test]
public void Parse_ExcessiveContent()
{
string json = @"[1,2,3]/*comment*/
//Another comment.
[]";

ExceptionAssert.Throws<JsonReaderException>(() => JArray.Parse(json),
"Additional text encountered after finished reading JSON content: [. Path '', line 3, position 0.");
}

[Test]
public void Parse_LineInfo()
{
Expand Down
25 changes: 25 additions & 0 deletions Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1994,5 +1994,30 @@ public void Parse_NoComments()
Assert.AreEqual(2, (int)o["prop"][1]);
Assert.AreEqual(3, (int)o["prop"][2]);
}

[Test]
public void Parse_ExcessiveContentJustComments()
{
string json = @"{'prop':[1,2,3]}/*comment*/
//Another comment.";

JObject o = JObject.Parse(json);

Assert.AreEqual(3, o["prop"].Count());
Assert.AreEqual(1, (int)o["prop"][0]);
Assert.AreEqual(2, (int)o["prop"][1]);
Assert.AreEqual(3, (int)o["prop"][2]);
}

[Test]
public void Parse_ExcessiveContent()
{
string json = @"{'prop':[1,2,3]}/*comment*/
//Another comment.
[]";

ExceptionAssert.Throws<JsonReaderException>(() => JObject.Parse(json),
"Additional text encountered after finished reading JSON content: [. Path '', line 3, position 0.");
}
}
}
25 changes: 25 additions & 0 deletions Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1264,5 +1264,30 @@ public void Parse_NoComments()
Assert.AreEqual(2, (int)o["prop"][1]);
Assert.AreEqual(3, (int)o["prop"][2]);
}

[Test]
public void Parse_ExcessiveContentJustComments()
{
string json = @"{'prop':[1,2,3]}/*comment*/
//Another comment.";

JToken o = JToken.Parse(json);

Assert.AreEqual(3, o["prop"].Count());
Assert.AreEqual(1, (int)o["prop"][0]);
Assert.AreEqual(2, (int)o["prop"][1]);
Assert.AreEqual(3, (int)o["prop"][2]);
}

[Test]
public void Parse_ExcessiveContent()
{
string json = @"{'prop':[1,2,3]}/*comment*/
//Another comment.
{}";

ExceptionAssert.Throws<JsonReaderException>(() => JToken.Parse(json),
"Additional text encountered after finished reading JSON content: {. Path '', line 3, position 0.");
}
}
}
47 changes: 46 additions & 1 deletion Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8253,7 +8253,52 @@ public void AdditionalContentAfterFinish()
reader.Read();

serializer.Deserialize(reader, typeof(MyType));
}, "Additional text found in JSON string after finishing deserializing object.");
}, "Additional text found in JSON string after finishing deserializing object. Path '[1]', line 1, position 5.");
}

[Test]
public void AdditionalContentAfterFinishCheckNotRequested()
{
string json = @"{ ""MyProperty"":{""Key"":""Value""}} A bunch of junk at the end of the json";

JsonSerializer serializer = new JsonSerializer();

var reader = new JsonTextReader(new StringReader(json));

MyType mt = (MyType)serializer.Deserialize(reader, typeof(MyType));
Assert.AreEqual(1, mt.MyProperty.Count);
}

[Test]
public void AdditionalContentAfterCommentsCheckNotRequested()
{
string json = @"{ ""MyProperty"":{""Key"":""Value""}} /*this is a comment */
// this is also a comment
This is just junk, though.";

JsonSerializer serializer = new JsonSerializer();

var reader = new JsonTextReader(new StringReader(json));

MyType mt = (MyType)serializer.Deserialize(reader, typeof(MyType));
Assert.AreEqual(1, mt.MyProperty.Count);
}

[Test]
public void AdditionalContentAfterComments()
{
string json = @"[{ ""MyProperty"":{""Key"":""Value""}} /*this is a comment */
// this is also a comment
,{}";

JsonSerializer serializer = new JsonSerializer();
serializer.CheckAdditionalContent = true;
var reader = new JsonTextReader(new StringReader(json));
reader.Read();
reader.Read();

ExceptionAssert.Throws<JsonSerializationException>(() => serializer.Deserialize(reader, typeof(MyType)),
"Additional text found in JSON string after finishing deserializing object. Path '[1]', line 3, position 2.");
}

[Test]
Expand Down
10 changes: 8 additions & 2 deletions Src/Newtonsoft.Json/JsonConvert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -962,9 +962,15 @@ public static void PopulateObject(string value, object target, JsonSerializerSet
{
jsonSerializer.Populate(jsonReader, target);

if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment)
if (settings != null && settings.CheckAdditionalContent)
{
throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
while (jsonReader.Read())
{
if (jsonReader.TokenType != JsonToken.Comment)
{
throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object.");
}
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Src/Newtonsoft.Json/Linq/JArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ internal override JToken CloneToken()
{
JArray a = Load(reader, settings);

if (reader.Read() && reader.TokenType != JsonToken.Comment)
while (reader.Read())
{
throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content.");
// Any content encountered here other than a comment will throw in the reader.
}

return a;
Expand Down
4 changes: 2 additions & 2 deletions Src/Newtonsoft.Json/Linq/JObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,9 @@ public JToken this[string propertyName]
{
JObject o = Load(reader, settings);

if (reader.Read() && reader.TokenType != JsonToken.Comment)
while (reader.Read())
{
throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content.");
// Any content encountered here other than a comment will throw in the reader.
}

return o;
Expand Down
5 changes: 3 additions & 2 deletions Src/Newtonsoft.Json/Linq/JToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2187,11 +2187,12 @@ public static JToken Parse(string json, JsonLoadSettings settings)
{
JToken t = Load(reader, settings);

if (reader.Read() && reader.TokenType != JsonToken.Comment)
while (reader.Read())
{
throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content.");
// Any content encountered here other than a comment will throw in the reader.
}


return t;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public object Deserialize(JsonReader reader, Type objectType, bool checkAddition
{
if (reader.TokenType != JsonToken.Comment)
{
throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
throw JsonSerializationException.Create(reader, "Additional text found in JSON string after finishing deserializing object.");
}
}
}
Expand Down

0 comments on commit 8956d3c

Please sign in to comment.