Skip to content

Commit

Permalink
Avoid GetConstructors in constraint validation
Browse files Browse the repository at this point in the history
Avoids bringing ConstructorInfo to simple apps.
  • Loading branch information
MichalStrehovsky committed Jan 24, 2023
1 parent a272954 commit 4da12e9
Showing 1 changed file with 42 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Reflection.Runtime.General;

using Internal.Reflection.Core.Execution;

using Debug = global::System.Diagnostics.Debug;

Expand Down Expand Up @@ -287,11 +290,47 @@ private static bool HasExplicitOrImplicitPublicDefaultConstructor(this Type type
if (type.IsValueType)
return true;

foreach (var ctor in type.GetConstructors())
// Look for a public parameterless constructor. Avoid Type.GetConstructors() so that we don't
// bring ConstructorInfo support into apps that don't use reflection.

RuntimeTypeHandle typeHandle = type.TypeHandle;

QTypeDefinition qTypeDefinition;
if (!ReflectionExecution.ExecutionEnvironment.TryGetMetadataForNamedType(typeHandle, out qTypeDefinition))
{
// Could be an array, reflection blocked type or something similar.
return false;
}

if (qTypeDefinition.IsNativeFormatMetadataBased)
{
if (!ctor.IsStatic && ctor.IsPublic && ctor.GetParametersNoCopy().Length == 0)
return true;
var reader = qTypeDefinition.NativeFormatReader;
foreach (var methodHandle in reader.GetTypeDefinition(qTypeDefinition.NativeFormatHandle).Methods)
{
var method = reader.GetMethod(methodHandle);
const MethodAttributes specialNameAttributes = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
if ((method.Flags & specialNameAttributes) == specialNameAttributes
&& (method.Flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Public
&& (method.Flags & MethodAttributes.Static) == 0)
{
var sig = reader.GetMethodSignature(method.Signature);
if (sig.Parameters.Count == 0 && method.Name.StringEquals(".ctor", reader))
{
return true;
}
}
}
}

#if ECMA_METADATA_SUPPORT
if (qTypeDefinition.IsEcmaFormatMetadataBased)
{
foreach (var ctor in type.GetConstructors())
if (!ctor.IsStatic && ctor.IsPublic && ctor.GetParametersNoCopy().Length == 0)
return true;
}
#endif

return false;
}

Expand Down

0 comments on commit 4da12e9

Please sign in to comment.