-Fixed error in JTokenWriter when disposing after adding a duplicate property

-Fixed not validating JSON when deserializing with DataTableConverter
This commit is contained in:
James Newton-King
2014-08-17 19:42:11 +12:00
parent 73a266217b
commit dce6228b8f
5 changed files with 53 additions and 18 deletions
@@ -41,6 +41,13 @@ namespace Newtonsoft.Json.Tests.Converters
{
public class DataSetConverterTests : TestFixtureBase
{
[Test]
public void DeserializeInvalidDataTable()
{
ExceptionAssert.Throws<JsonException>("Unexpected JSON token when reading DataTable. Expected StartArray, got Integer. Path 'pending_count', line 1, position 19.",
() => JsonConvert.DeserializeObject<DataSet>("{\"pending_count\":23,\"completed_count\":45}"));
}
[Test]
public void SerializeAndDeserialize()
{
@@ -7892,6 +7892,18 @@ Parameter name: value",
}
#endif
[Test]
public void DuplicatePropertiesInNestedObject()
{
ExceptionAssert.Throws<ArgumentException>(
"Can not add property time to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.",
() =>
{
string content = @"{""result"":{""time"":1408188592,""time"":1408188593},""error"":null,""id"":""1""}";
JsonConvert.DeserializeObject<JObject>(content);
});
}
[Test]
public void RoundtripUriOriginalString()
{
@@ -77,7 +77,7 @@ namespace Newtonsoft.Json.Converters
DataTableConverter converter = new DataTableConverter();
reader.Read();
CheckedRead(reader);
while (reader.TokenType == JsonToken.PropertyName)
{
@@ -89,7 +89,7 @@ namespace Newtonsoft.Json.Converters
if (!exists)
ds.Tables.Add(dt);
reader.Read();
CheckedRead(reader);
}
return ds;
@@ -106,6 +106,12 @@ namespace Newtonsoft.Json.Converters
{
return typeof(DataSet).IsAssignableFrom(valueType);
}
private void CheckedRead(JsonReader reader)
{
if (!reader.Read())
throw JsonSerializationException.Create(reader, "Unexpected end when reading DataSet.");
}
}
}
@@ -92,17 +92,19 @@ namespace Newtonsoft.Json.Converters
{
dt.TableName = (string)reader.Value;
reader.Read();
CheckedRead(reader);
}
if (reader.TokenType == JsonToken.StartArray)
reader.Read();
if (reader.TokenType != JsonToken.StartArray)
throw JsonSerializationException.Create(reader, "Unexpected JSON token when reading DataTable. Expected StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
CheckedRead(reader);
while (reader.TokenType != JsonToken.EndArray)
{
CreateRow(reader, dt);
reader.Read();
CheckedRead(reader);
}
return dt;
@@ -111,13 +113,13 @@ namespace Newtonsoft.Json.Converters
private static void CreateRow(JsonReader reader, DataTable dt)
{
DataRow dr = dt.NewRow();
reader.Read();
CheckedRead(reader);
while (reader.TokenType == JsonToken.PropertyName)
{
string columnName = (string)reader.Value;
reader.Read();
CheckedRead(reader);
DataColumn column = dt.Columns[columnName];
if (column == null)
@@ -130,7 +132,7 @@ namespace Newtonsoft.Json.Converters
if (column.DataType == typeof(DataTable))
{
if (reader.TokenType == JsonToken.StartArray)
reader.Read();
CheckedRead(reader);
DataTable nestedDt = new DataTable();
@@ -138,7 +140,7 @@ namespace Newtonsoft.Json.Converters
{
CreateRow(reader, nestedDt);
reader.Read();
CheckedRead(reader);
}
dr[columnName] = nestedDt;
@@ -146,14 +148,14 @@ namespace Newtonsoft.Json.Converters
else if (column.DataType.IsArray && column.DataType != typeof(byte[]))
{
if (reader.TokenType == JsonToken.StartArray)
reader.Read();
CheckedRead(reader);
List<object> o = new List<object>();
while (reader.TokenType != JsonToken.EndArray)
{
o.Add(reader.Value);
reader.Read();
CheckedRead(reader);
}
Array destinationArray = Array.CreateInstance(column.DataType.GetElementType(), o.Count);
@@ -165,8 +167,8 @@ namespace Newtonsoft.Json.Converters
{
dr[columnName] = reader.Value ?? DBNull.Value;
}
reader.Read();
CheckedRead(reader);
}
dr.EndEdit();
@@ -190,17 +192,23 @@ namespace Newtonsoft.Json.Converters
case JsonToken.Undefined:
return typeof(string);
case JsonToken.StartArray:
reader.Read();
CheckedRead(reader);
if (reader.TokenType == JsonToken.StartObject)
return typeof(DataTable); // nested datatable
Type arrayType = GetColumnDataType(reader);
return arrayType.MakeArrayType();
default:
throw new JsonException("Unexpected JSON token while reading DataTable: {0}".FormatWith(CultureInfo.InvariantCulture, tokenType));
throw JsonSerializationException.Create(reader, "Unexpected JSON token when reading DataTable: {0}".FormatWith(CultureInfo.InvariantCulture, tokenType));
}
}
private static void CheckedRead(JsonReader reader)
{
if (!reader.Read())
throw JsonSerializationException.Create(reader, "Unexpected end when reading DataTable.");
}
/// <summary>
/// Determines whether this instance can convert the specified value type.
/// </summary>
+4 -2
View File
@@ -155,9 +155,11 @@ namespace Newtonsoft.Json.Linq
/// <param name="name">The name of the property.</param>
public override void WritePropertyName(string name)
{
base.WritePropertyName(name);
AddParent(new JProperty(name));
// don't set state until after in case of an error such as duplicate property names
// incorrect state will cause issues if writer is disposed when closing open properties
base.WritePropertyName(name);
}
private void AddValue(object value, JsonToken token)