From 5cc27cf039da6ebb8638f9a770508c6ed32354fe Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Thu, 13 Jun 2019 15:10:13 -0700 Subject: [PATCH] Correcting some invalid array json inputs (dotnet/corefx#38323) * correcting some invalid array json inputs * adding comments and modifiers * addressing feedback * correcting issue number Commit migrated from https://github.com/dotnet/corefx/commit/eaee16b5c9d3e020b5892a28a204ceb5da4d6a4a --- .../Serialization/JsonPropertyInfoNotNullable.cs | 8 +++++++ .../JsonSerializer.Read.HandleArray.cs | 7 +++++- .../JsonSerializer.Read.HandleDictionary.cs | 5 +++++ .../tests/Serialization/DictionaryTests.cs | 26 ++++++++++++++++++++-- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs index 07920e8..9914128 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs @@ -52,12 +52,20 @@ namespace System.Text.Json { Debug.Assert(ShouldDeserialize); + // We need a property in order to a apply a value in a dictionary. if (state.Current.KeyName == null && (state.Current.IsProcessingDictionary || state.Current.IsProcessingImmutableDictionary)) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(RuntimePropertyType, reader, state.JsonPath); return; } + // We need an initialized array in order to store the values. + if (state.Current.IsProcessingEnumerable && state.Current.TempEnumerableValues == null && state.Current.ReturnValue == null) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(RuntimePropertyType, reader, state.JsonPath); + return; + } + if (ValueConverter == null || !ValueConverter.TryRead(RuntimePropertyType, ref reader, out TRuntimeProperty value)) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(RuntimePropertyType, reader, state.JsonPath); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs index 95cc63e..7ee0975 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs @@ -162,7 +162,12 @@ namespace System.Text.Json } else { - ((IList)state.Current.ReturnValue).Add(value); + if (!(state.Current.ReturnValue is IList list)) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(value.GetType(), reader, state.JsonPath); + return; + } + list.Add(value); } } else if (!setPropertyDirectly && state.Current.IsEnumerableProperty) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleDictionary.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleDictionary.cs index c1eae715..9c7f73d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleDictionary.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleDictionary.cs @@ -46,6 +46,11 @@ namespace System.Text.Json } else { + if (classInfo.CreateObject == null) + { + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(classInfo.Type, reader, state.JsonPath); + return; + } state.Current.ReturnValue = classInfo.CreateObject(); } return; diff --git a/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.cs b/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.cs index c845e4b..fbe5a18 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/DictionaryTests.cs @@ -124,12 +124,34 @@ namespace System.Text.Json.Serialization.Tests Assert.Throws(() => JsonSerializer.Parse(json, type)); } + [Theory] + [InlineData(typeof(int[]), @"""test""")] + [InlineData(typeof(int[]), @"1")] + [InlineData(typeof(int[]), @"false")] + [InlineData(typeof(int[]), @"{}")] + [InlineData(typeof(int[]), @"[""test""")] + [InlineData(typeof(int[]), @"[true]")] + // [InlineData(typeof(int[]), @"[{}]")] TODO #38485: Uncomment when fixed + [InlineData(typeof(int[]), @"[[]]")] + [InlineData(typeof(Dictionary), @"{""test"": {}}")] + [InlineData(typeof(Dictionary), @"{""test"": ""test""}")] + [InlineData(typeof(Dictionary), @"{""test"": 1}")] + [InlineData(typeof(Dictionary), @"{""test"": true}")] + [InlineData(typeof(Dictionary), @"{""test"": [""test""]}")] + [InlineData(typeof(Dictionary), @"{""test"": [[]]}")] + // [InlineData(typeof(Dictionary), @"{""test"": [{}]}")] TODO #38485: Uncomment when fixed + public static void InvalidJsonForArrayShouldFail(Type type, string json) + { + Assert.Throws(() => JsonSerializer.Parse(json, type)); + } + [Fact] public static void InvalidEmptyDictionaryInput() { Assert.Throws(() => JsonSerializer.Parse("{}")); } + [Fact] public static void PocoWithDictionaryObject() { PocoDictionary dict = JsonSerializer.Parse("{\n\t\"key\" : {\"a\" : \"b\", \"c\" : \"d\"}}"); @@ -137,7 +159,7 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal(dict.key["c"], "d"); } - class PocoDictionary + public class PocoDictionary { public Dictionary key { get; set; } } @@ -160,7 +182,7 @@ namespace System.Text.Json.Serialization.Tests Assert.Equal(@"{""Id"":10}", element.ToString()); } - class Poco + public class Poco { public int Id { get; set; } } -- 2.7.4