Skip to content

Commit 5ebe672

Browse files
Fixed StackOverflowException generated by Guard.NotNull <> TypeExtensions.IsNullableType
1 parent c2e1a65 commit 5ebe672

File tree

2 files changed

+29
-44
lines changed

2 files changed

+29
-44
lines changed

src/DotNetToolkit.Repository/Extensions/Internal/TypeExtensions.cs

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ internal static class TypeExtensions
1818
/// <returns>The default value of the specified type.</returns>
1919
public static object GetDefault([NotNull] this Type type)
2020
{
21-
Guard.NotNull(type, nameof(type));
22-
23-
return type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) : null;
21+
return type == null ? null : (type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) : null);
2422
}
2523

2624
/// <summary>
@@ -30,9 +28,7 @@ public static object GetDefault([NotNull] this Type type)
3028
/// <returns><c>true</c> if the specified type is a <see cref="ICollection{T}"/>; otherwise, <c>false</c>.</returns>
3129
public static bool IsGenericCollection([NotNull] this Type type)
3230
{
33-
Guard.NotNull(type, nameof(type));
34-
35-
return type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(ICollection<>);
31+
return type != null && type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(ICollection<>);
3632
}
3733

3834
/// <summary>
@@ -42,9 +38,7 @@ public static bool IsGenericCollection([NotNull] this Type type)
4238
/// <returns><c>true</c> if the specified type is nullable; otherwise, <c>false</c>.</returns>
4339
public static bool IsNullableType([NotNull] this Type type)
4440
{
45-
Guard.NotNull(type, nameof(type));
46-
47-
return type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
41+
return type != null && type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
4842
}
4943

5044
/// <summary>
@@ -54,7 +48,7 @@ public static bool IsNullableType([NotNull] this Type type)
5448
/// <returns><c>true</c> if the specified type is enumerable; otherwise, <c>false</c>.</returns>
5549
public static bool IsEnumerable([NotNull] this Type type)
5650
{
57-
return typeof(IEnumerable).IsAssignableFrom(Guard.NotNull(type, nameof(type)));
51+
return type != null && typeof(IEnumerable).IsAssignableFrom(Guard.NotNull(type, nameof(type)));
5852
}
5953

6054
/// <summary>
@@ -65,12 +59,12 @@ public static bool IsEnumerable([NotNull] this Type type)
6559
/// <returns><c>true</c> if specified type implements the specified interface type; otherwise, <c>false</c>.</returns>
6660
public static bool ImplementsInterface([NotNull] this Type type, [NotNull] Type interfaceType)
6761
{
68-
Guard.NotNull(type, nameof(type));
69-
Guard.NotNull(interfaceType, nameof(interfaceType));
70-
71-
return interfaceType.IsAssignableFrom(type) ||
72-
type.IsGenericType(interfaceType) ||
73-
type.GetTypeInfo().ImplementedInterfaces.Any(@interface => IsGenericType(@interface, interfaceType));
62+
return type != null && interfaceType != null &&
63+
(
64+
interfaceType.IsAssignableFrom(type) ||
65+
type.IsGenericType(interfaceType) ||
66+
type.GetTypeInfo().ImplementedInterfaces.Any(@interface => IsGenericType(@interface, interfaceType))
67+
);
7468
}
7569

7670
/// <summary>
@@ -81,10 +75,7 @@ public static bool ImplementsInterface([NotNull] this Type type, [NotNull] Type
8175
/// <returns><c>true</c> if the specified type is a generic type of the specified interface type; otherwise, <c>false</c>.</returns>
8276
public static bool IsGenericType([NotNull] this Type type, [NotNull] Type genericType)
8377
{
84-
Guard.NotNull(type, nameof(type));
85-
Guard.NotNull(genericType, nameof(genericType));
86-
87-
return type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == genericType;
78+
return type != null && genericType != null && type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == genericType;
8879
}
8980

9081
/// <summary>
@@ -95,7 +86,8 @@ public static bool IsGenericType([NotNull] this Type type, [NotNull] Type generi
9586
/// <returns>The converted result.</returns>
9687
public static object ConvertTo([NotNull] this Type type, [CanBeNull] string value)
9788
{
98-
Guard.NotNull(type, nameof(type));
89+
if (type == null)
90+
return null;
9991

10092
object Result = null;
10193

@@ -167,7 +159,8 @@ public static object ConvertTo([NotNull] this Type type, [CanBeNull] string valu
167159
/// <returns>The new instance of the specified type.</returns>
168160
public static object InvokeConstructor([NotNull] this Type type, [CanBeNull] Dictionary<string, string> keyValues)
169161
{
170-
Guard.NotNull(type, nameof(type));
162+
if (type == null)
163+
return null;
171164

172165
if (keyValues == null || keyValues.Count == 0)
173166
return Activator.CreateInstance(type);
@@ -220,20 +213,20 @@ select pi
220213
{
221214
// Try to get all the values for the parameters we already have,
222215
// and set the rest to their default value
223-
var args = matchedCtorParams.Value.Select(pi =>
224-
{
225-
// If we find a matching parameter, then delete it from the collection,
226-
// that way we don't try to initialize a property that has the same name
227-
if (kvs.ContainsKey(pi.Name))
228-
{
229-
kvs.TryGetValue(pi.Name, out var value);
230-
kvs.Remove(pi.Name);
231-
232-
return pi.ParameterType.ConvertTo(value);
233-
}
234-
235-
return pi.ParameterType.GetDefault();
236-
}).ToArray();
216+
var args = matchedCtorParams.Value.Select(pi =>
217+
{
218+
// If we find a matching parameter, then delete it from the collection,
219+
// that way we don't try to initialize a property that has the same name
220+
if (kvs.ContainsKey(pi.Name))
221+
{
222+
kvs.TryGetValue(pi.Name, out var value);
223+
kvs.Remove(pi.Name);
224+
225+
return pi.ParameterType.ConvertTo(value);
226+
}
227+
228+
return pi.ParameterType.GetDefault();
229+
}).ToArray();
237230

238231
obj = matchedCtorParams.Key.Invoke(args);
239232
}

src/DotNetToolkit.Repository/Utility/Guard.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ internal static class Guard
1616
[ContractAnnotation("value:null => halt")]
1717
public static T NotNull<T>([ValidatedNotNull] [NoEnumeration] T value, [InvokerParameterName] string parameterName)
1818
{
19-
#if NETSTANDARD2_0
20-
if (typeof(T).IsNullableType() && value == null)
21-
#else
2219
if (ReferenceEquals(value, null))
23-
#endif
2420
{
2521
NotEmpty(parameterName, nameof(parameterName));
2622

@@ -74,11 +70,7 @@ public static ICollection<T> NotEmpty<T>([ValidatedNotNull] [NoEnumeration] ICol
7470
[ContractAnnotation("value:null => halt")]
7571
public static T EnsureNotNull<T>([ValidatedNotNull] [NoEnumeration] T value, string message) where T : class
7672
{
77-
#if NETSTANDARD2_0
78-
if (typeof(T).IsNullableType() && value == null)
79-
#else
8073
if (ReferenceEquals(value, null))
81-
#endif
8274
throw new InvalidOperationException(message);
8375

8476
return value;

0 commit comments

Comments
 (0)