Skip to content

Commit

Permalink
Argument tests for CreateJsonTypeInfo and CreateJsonPropertyInfo (#71324
Browse files Browse the repository at this point in the history
)

* Argument tests for CreateJsonTypeInfo and CreateJsonPropertyInfo

* add check for typeof(void) - possibly workaround #71339
  • Loading branch information
krwq committed Jun 27, 2022
1 parent 6f7064d commit 5be7092
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,11 @@ internal virtual void LateAddProperties() { }
[RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use generic overload or System.Text.Json source generation for native AOT applications.")]
public static JsonTypeInfo<T> CreateJsonTypeInfo<T>(JsonSerializerOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}

return new CustomJsonTypeInfo<T>(options);
}

Expand All @@ -427,6 +432,21 @@ public static JsonTypeInfo<T> CreateJsonTypeInfo<T>(JsonSerializerOptions option
[RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use generic overload or System.Text.Json source generation for native AOT applications.")]
public static JsonTypeInfo CreateJsonTypeInfo(Type type, JsonSerializerOptions options)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}

if (options == null)
{
throw new ArgumentNullException(nameof(options));
}

if (IsInvalidForSerialization(type))
{
ThrowHelper.ThrowArgumentException_CannotSerializeInvalidType(nameof(type), type, null, null);
}

s_createJsonTypeInfo ??= typeof(JsonTypeInfo).GetMethod(nameof(CreateJsonTypeInfo), new Type[] { typeof(JsonSerializerOptions) })!;
return (JsonTypeInfo)s_createJsonTypeInfo.MakeGenericMethod(type)
.Invoke(null, new object[] { options })!;
Expand All @@ -440,7 +460,20 @@ public static JsonTypeInfo CreateJsonTypeInfo(Type type, JsonSerializerOptions o
/// <returns>JsonPropertyInfo instance</returns>
public JsonPropertyInfo CreateJsonPropertyInfo(Type propertyType, string name)
{
ValidateType(propertyType, Type, null, Options);
if (propertyType == null)
{
throw new ArgumentNullException(nameof(propertyType));
}

if (name == null)
{
throw new ArgumentNullException(nameof(name));
}

if (IsInvalidForSerialization(propertyType))
{
ThrowHelper.ThrowArgumentException_CannotSerializeInvalidType(nameof(propertyType), propertyType, Type, name);
}

JsonConverter converter = GetConverter(propertyType,
parentClassType: null,
Expand Down Expand Up @@ -609,7 +642,7 @@ internal static void ValidateType(Type type, Type? parentClassType, MemberInfo?

internal static bool IsInvalidForSerialization(Type type)
{
return type.IsPointer || type.IsByRef || IsByRefLike(type) || type.ContainsGenericParameters;
return type == typeof(void) || type.IsPointer || type.IsByRef || IsByRefLike(type) || type.ContainsGenericParameters;
}

private static bool IsByRefLike(Type type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ public static void ThrowJsonException(string? message = null)
throw new JsonException(message) { AppendPathInformation = true };
}

[DoesNotReturn]
public static void ThrowArgumentException_CannotSerializeInvalidType(string paramName, Type type, Type? parentClassType, string? propertyName)
{
if (parentClassType == null)
{
Debug.Assert(propertyName == null);
throw new ArgumentException(SR.Format(SR.CannotSerializeInvalidType, type), paramName);
}

Debug.Assert(propertyName != null);
throw new ArgumentException(SR.Format(SR.CannotSerializeInvalidMember, type, propertyName, parentClassType), paramName);
}

[DoesNotReturn]
public static void ThrowInvalidOperationException_CannotSerializeInvalidType(Type type, Type? parentClassType, MemberInfo? memberInfo)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,54 @@ public static void AddingNullJsonPropertyInfoIsNotPossible()
Assert.NotNull(typeInfo.Properties[0]);
}

[Fact]
public static void CreateJsonTypeInfoWithNullArgumentsThrows()
{
Assert.Throws<ArgumentNullException>(() => JsonTypeInfo.CreateJsonTypeInfo(null, new JsonSerializerOptions()));
Assert.Throws<ArgumentNullException>(() => JsonTypeInfo.CreateJsonTypeInfo(typeof(string), null));
Assert.Throws<ArgumentNullException>(() => JsonTypeInfo.CreateJsonTypeInfo(null, null));
Assert.Throws<ArgumentNullException>(() => JsonTypeInfo.CreateJsonTypeInfo<string>(null));
}

[Theory]
[InlineData(typeof(void))]
[InlineData(typeof(Dictionary<,>))]
[InlineData(typeof(List<>))]
[InlineData(typeof(Nullable<>))]
[InlineData(typeof(int*))]
[InlineData(typeof(RefStruct))]
public static void CreateJsonTypeInfoWithInappropriateTypeThrows(Type type)
{
Assert.Throws<ArgumentException>(() => JsonTypeInfo.CreateJsonTypeInfo(type, new JsonSerializerOptions()));
}

ref struct RefStruct
{
public int Foo { get; set; }
}

[Fact]
public static void CreateJsonPropertyInfoWithNullArgumentsThrows()
{
JsonTypeInfo ti = JsonTypeInfo.CreateJsonTypeInfo<MyClass>(new JsonSerializerOptions());
Assert.Throws<ArgumentNullException>(() => ti.CreateJsonPropertyInfo(null, "test"));
Assert.Throws<ArgumentNullException>(() => ti.CreateJsonPropertyInfo(typeof(string), null));
Assert.Throws<ArgumentNullException>(() => ti.CreateJsonPropertyInfo(null, null));
}

[Theory]
[InlineData(typeof(void))]
[InlineData(typeof(Dictionary<,>))]
[InlineData(typeof(List<>))]
[InlineData(typeof(Nullable<>))]
[InlineData(typeof(int*))]
[InlineData(typeof(RefStruct))]
public static void CreateJsonPropertyInfoWithInappropriateTypeThrows(Type type)
{
JsonTypeInfo ti = JsonTypeInfo.CreateJsonTypeInfo<MyClass>(new JsonSerializerOptions());
Assert.Throws<ArgumentException>(() => ti.CreateJsonPropertyInfo(type, "test"));
}

[Theory]
[InlineData(typeof(object))]
[InlineData(typeof(string))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,14 @@ public static void ModifiersAreCalledAndModifyTypeInfos()
Assert.True(secondModifierCalled);
}

[Fact]
public static void AddingNullModifierThrows()
{
DefaultJsonTypeInfoResolver r = new();
Assert.Throws<ArgumentNullException>(() => r.Modifiers.Add(null));
Assert.Throws<ArgumentNullException>(() => r.Modifiers.Insert(0, null));
}

private static void InvokeGeneric(Type type, string methodName, params object[] args)
{
typeof(DefaultJsonTypeInfoResolverTests)
Expand Down

0 comments on commit 5be7092

Please sign in to comment.