Added ScriptEngine.DisableDynamicBinding as additional mitigation for GitHub Issue #400.

This commit is contained in:
ClearScript 2022-07-08 13:25:48 -04:00
Родитель 7d5224416d
Коммит 29db0c14b9
2 изменённых файлов: 40 добавлений и 13 удалений

Просмотреть файл

@ -117,26 +117,35 @@ namespace Microsoft.ClearScript
}
else
{
result = BindMethodInternal(signature, AccessContext, bindFlags, Target, name, typeArgs, args, bindArgs);
if (!result.IsPreferredMethod(this, name))
{
if (result is MethodBindSuccess)
{
result = new MethodBindFailure(() => new MissingMemberException(MiscHelpers.FormatInvariant("The object has no method named '{0}' that matches the specified arguments", name)));
}
var forceReflection = Engine.DisableDynamicBinding;
foreach (var altName in GetAltMethodNames(name, bindFlags))
if (forceReflection)
{
result = new MethodBindFailure(() => new MissingMemberException(MiscHelpers.FormatInvariant("The object has no method named '{0}' that matches the specified arguments", name)));
}
else
{
result = BindMethodInternal(signature, AccessContext, bindFlags, Target, name, typeArgs, args, bindArgs);
if (!result.IsPreferredMethod(this, name))
{
var altResult = BindMethodInternal(null, AccessContext, bindFlags, Target, altName, typeArgs, args, bindArgs);
if (altResult.IsUnblockedMethod(this))
if (result is MethodBindSuccess)
{
result = altResult;
break;
result = new MethodBindFailure(() => new MissingMemberException(MiscHelpers.FormatInvariant("The object has no method named '{0}' that matches the specified arguments", name)));
}
foreach (var altName in GetAltMethodNames(name, bindFlags))
{
var altResult = BindMethodInternal(null, AccessContext, bindFlags, Target, altName, typeArgs, args, bindArgs);
if (altResult.IsUnblockedMethod(this))
{
result = altResult;
break;
}
}
}
}
if ((result is MethodBindFailure) && Engine.UseReflectionBindFallback)
if ((result is MethodBindFailure) && (forceReflection || Engine.UseReflectionBindFallback))
{
var reflectionResult = BindMethodUsingReflection(bindFlags, Target, name, typeArgs, args);
if (reflectionResult is MethodBindSuccess)

Просмотреть файл

@ -264,14 +264,32 @@ namespace Microsoft.ClearScript
/// </remarks>
public bool DisableFloatNarrowing { get; set; }
/// <summary>
/// Enables or disables dynamic method binding.
/// </summary>
/// <remarks>
/// When this property is set to <c>true</c>, the script engine bypasses the default method
/// binding algorithm and uses reflection-based method binding instead. This approach
/// abandons support for generic methods and other features, but it avoids engaging the
/// dynamic infrastructure.
/// </remarks>
/// <seealso cref="UseReflectionBindFallback"/>
public bool DisableDynamicBinding { get; set; }
/// <summary>
/// Enables or disables the use of reflection-based method binding as a fallback.
/// </summary>
/// <remarks>
/// <para>
/// When this property is set to <c>true</c>, the script engine attempts to use
/// reflection-based method binding when the default method binding algorithm fails. This
/// approach reduces type safety, but it may be useful for running legacy scripts that rely
/// on the specific behavior of reflection-based method binding.
/// </para>
/// <para>
/// This property has no effect when <see cref="DisableDynamicBinding"/> is set to
/// <c>true</c>.
/// </para>
/// </remarks>
public bool UseReflectionBindFallback { get; set; }