-Fixed error in JTokenWriter when disposing after adding a duplicate property
-Fixed not validating JSON when deserializing with DataTableConverter
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user