Skip to content

Commit

Permalink
[Debug] IndexOutOfRangeException when extension data doesn't have two…
Browse files Browse the repository at this point in the history
… generic parameters (#33014)

* added generic param tests

* added proposed fix

* fixed debug statements to use underlying dictionary type

* removed baseline comment

* removed casts to idictionary

* using explicitly typed variable

Co-Authored-By: Layomi Akinrinade <layomia@gmail.com>

Co-authored-by: Layomi Akinrinade <layomia@gmail.com>
  • Loading branch information
alanisaac and layomia authored Mar 2, 2020
1 parent 0bf721a commit 71deb1e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;
Expand Down Expand Up @@ -106,23 +107,27 @@ private static void CreateDataExtensionProperty(
{
Debug.Assert(jsonPropertyInfo != null);

IDictionary? extensionData = (IDictionary?)jsonPropertyInfo.GetValueAsObject(obj);
object? extensionData = jsonPropertyInfo.GetValueAsObject(obj);
if (extensionData == null)
{
// Create the appropriate dictionary type. We already verified the types.
Debug.Assert(jsonPropertyInfo.DeclaredPropertyType.IsGenericType);
Debug.Assert(jsonPropertyInfo.DeclaredPropertyType.GetGenericArguments().Length == 2);
Debug.Assert(jsonPropertyInfo.DeclaredPropertyType.GetGenericArguments()[0].UnderlyingSystemType == typeof(string));
Debug.Assert(
jsonPropertyInfo.DeclaredPropertyType.GetGenericArguments()[1].UnderlyingSystemType == typeof(object) ||
jsonPropertyInfo.DeclaredPropertyType.GetGenericArguments()[1].UnderlyingSystemType == typeof(JsonElement));
#if DEBUG
Type underlyingIDictionaryType = jsonPropertyInfo.DeclaredPropertyType.GetCompatibleGenericInterface(typeof(IDictionary<,>))!;
Type[] genericArgs = underlyingIDictionaryType.GetGenericArguments();

Debug.Assert(underlyingIDictionaryType.IsGenericType);
Debug.Assert(genericArgs.Length == 2);
Debug.Assert(genericArgs[0].UnderlyingSystemType == typeof(string));
Debug.Assert(
genericArgs[1].UnderlyingSystemType == typeof(object) ||
genericArgs[1].UnderlyingSystemType == typeof(JsonElement));
#endif
if (jsonPropertyInfo.RuntimeClassInfo.CreateObject == null)
{
ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(jsonPropertyInfo.DeclaredPropertyType);
}

extensionData = (IDictionary?)jsonPropertyInfo.RuntimeClassInfo.CreateObject();
extensionData = jsonPropertyInfo.RuntimeClassInfo.CreateObject();
jsonPropertyInfo.SetValueAsObject(obj, extensionData);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,31 @@ private class ClassWithExtensionPropertyCustomIImmutableJsonElement
public GenericIImmutableDictionaryWrapper<string, JsonElement> MyOverflow { get; set; }
}

[Fact]
public static void DeserializeIntoGenericDictionaryParameterCount()
{
JsonSerializer.Deserialize<ClassWithExtensionPropertyNoGenericParameters>("{\"hello\":\"world\"}");
JsonSerializer.Deserialize<ClassWithExtensionPropertyOneGenericParameter>("{\"hello\":\"world\"}");
JsonSerializer.Deserialize<ClassWithExtensionPropertyThreeGenericParameters>("{\"hello\":\"world\"}");
}

private class ClassWithExtensionPropertyNoGenericParameters
{
[JsonExtensionData]
public StringToObjectIDictionaryWrapper MyOverflow { get; set; }
}

private class ClassWithExtensionPropertyOneGenericParameter
{
[JsonExtensionData]
public StringToGenericIDictionaryWrapper<object> MyOverflow { get; set; }
}

private class ClassWithExtensionPropertyThreeGenericParameters
{
[JsonExtensionData]
public GenericIDictonaryWrapperThreeGenericParameters<string, object, string> MyOverflow { get; set; }
}

[Fact]
public static void CustomObjectConverterInExtensionProperty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,8 @@ public class GenericIDictionaryWrapperPrivateConstructor<TKey, TValue> : Generic
private GenericIDictionaryWrapperPrivateConstructor() { }
}

public class GenericIDictonaryWrapperThreeGenericParameters<TKey, TValue, TUnused> : GenericIDictionaryWrapper<TKey, TValue> { }

public class ReadOnlyStringToStringIDictionaryWrapper : StringToStringIDictionaryWrapper
{
public override bool IsReadOnly => true;
Expand Down

0 comments on commit 71deb1e

Please sign in to comment.