Skip to content

Commit baa1e21

Browse files
authored
Fix deserializing incomplete JSON object to JObject (#2181)
1 parent 541eab2 commit baa1e21

File tree

3 files changed

+92
-2
lines changed

3 files changed

+92
-2
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#region License
2+
// Copyright (c) 2007 James Newton-King
3+
//
4+
// Permission is hereby granted, free of charge, to any person
5+
// obtaining a copy of this software and associated documentation
6+
// files (the "Software"), to deal in the Software without
7+
// restriction, including without limitation the rights to use,
8+
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the
10+
// Software is furnished to do so, subject to the following
11+
// conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be
14+
// included in all copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23+
// OTHER DEALINGS IN THE SOFTWARE.
24+
#endregion
25+
26+
using System;
27+
using System.IO;
28+
#if !(NET20 || NET35 || NET40 || PORTABLE40)
29+
using System.Threading.Tasks;
30+
#endif
31+
using Newtonsoft.Json.Linq;
32+
#if DNXCORE50
33+
using Xunit;
34+
using Test = Xunit.FactAttribute;
35+
using Assert = Newtonsoft.Json.Tests.XUnitAssert;
36+
#else
37+
using NUnit.Framework;
38+
#endif
39+
40+
namespace Newtonsoft.Json.Tests.Issues
41+
{
42+
[TestFixture]
43+
public class Issue2165
44+
{
45+
[Test]
46+
public void Test_Deserializer()
47+
{
48+
ExceptionAssert.Throws<JsonWriterException>(
49+
() => JsonConvert.DeserializeObject<JObject>("{"),
50+
"Unexpected end when reading token. Path ''.");
51+
}
52+
53+
[Test]
54+
public void Test()
55+
{
56+
StringWriter w = new StringWriter();
57+
JsonTextWriter writer = new JsonTextWriter(w);
58+
59+
var jsonReader = new JsonTextReader(new StringReader("{"));
60+
jsonReader.Read();
61+
62+
ExceptionAssert.Throws<JsonWriterException>(
63+
() => writer.WriteToken(jsonReader),
64+
"Unexpected end when reading token. Path ''.");
65+
}
66+
67+
#if !(NET20 || NET35 || NET40 || PORTABLE40)
68+
[Test]
69+
public async Task TestAsync()
70+
{
71+
StringWriter w = new StringWriter();
72+
JsonTextWriter writer = new JsonTextWriter(w);
73+
74+
var jsonReader = new JsonTextReader(new StringReader("{"));
75+
await jsonReader.ReadAsync();
76+
77+
await ExceptionAssert.ThrowsAsync<JsonWriterException>(
78+
() => writer.WriteTokenAsync(jsonReader),
79+
"Unexpected end when reading token. Path ''.");
80+
}
81+
#endif
82+
}
83+
}

Src/Newtonsoft.Json/JsonWriter.Async.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ internal virtual async Task WriteTokenAsync(JsonReader reader, bool writeChildre
785785
&& writeChildren
786786
&& await reader.ReadAsync(cancellationToken).ConfigureAwait(false));
787787

788-
if (initialDepth < CalculateWriteTokenFinalDepth(reader))
788+
if (IsWriteTokenIncomplete(reader, writeChildren, initialDepth))
789789
{
790790
throw JsonWriterException.Create(this, "Unexpected end when reading token.", null);
791791
}

Src/Newtonsoft.Json/JsonWriter.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,12 +666,19 @@ internal virtual void WriteToken(JsonReader reader, bool writeChildren, bool wri
666666
&& writeChildren
667667
&& reader.Read());
668668

669-
if (initialDepth < CalculateWriteTokenFinalDepth(reader))
669+
if (IsWriteTokenIncomplete(reader, writeChildren, initialDepth))
670670
{
671671
throw JsonWriterException.Create(this, "Unexpected end when reading token.", null);
672672
}
673673
}
674674

675+
private bool IsWriteTokenIncomplete(JsonReader reader, bool writeChildren, int initialDepth)
676+
{
677+
int finalDepth = CalculateWriteTokenFinalDepth(reader);
678+
return initialDepth < finalDepth ||
679+
(writeChildren && initialDepth == finalDepth && JsonTokenUtils.IsStartToken(reader.TokenType));
680+
}
681+
675682
private int CalculateWriteTokenInitialDepth(JsonReader reader)
676683
{
677684
JsonToken type = reader.TokenType;

0 commit comments

Comments
 (0)