Skip to content

FindPublicMethodBySignature may incorrectly match String.Equals(String, String) when enum overload is intended #14190

Description

@lewing

Summary

PR #14079 introduced FindPublicMethodBySignature in the LateBindExecute fallback path. We believe this may cause a regression when property functions use methods with enum parameters passed as strings (e.g., StringComparison).

Suspected Behavior Change

The condition pattern used in runtime's Directory.Build.targets:

Condition="!$(TargetOS.Equals($(TargetOS.ToLower()), StringComparison.InvariantCulture))"

In the LateBindExecute path, the types[] array is built from the argument runtime types - all typeof(string) since MSBuild args start as strings.

Old behavior: Type.GetMethod(name, bindingFlags, null, types, null) with DefaultBinder appears to return null (possibly due to ambiguous match between String.Equals(String, String) and Object.Equals(Object, Object)), causing fallthrough to the CoerceArguments loop which correctly parses "StringComparison.InvariantCulture" as an enum value.

New behavior: FindPublicMethodBySignature iterates GetMethods() and does strict ParameterType != types[i] matching. It finds String.Equals(String, String) (exact match for [string, string]) and returns it. This invokes the ordinal string comparison with the literal string "StringComparison.InvariantCulture" as the second argument, returning false instead of the expected true.

Observed Impact

In the VMR (dotnet/dotnet), PR #7406 (msbuild flow to main) fails in the SB_CentOSStream10_Offline leg with:

error : The passed-in TargetOS property value 'linux' must be lowercase

The Offline leg is the first consumer of the newly-built MSBuild (built from the Online leg's output SDK). Online legs using the older Microsoft SDK pass fine.

Reproduction (partial)

We confirmed the behavior difference with a standalone test on .NET 11:

Type type = typeof(string);
Type[] types = [typeof(string), typeof(string)];

// OLD path: GetMethod returns null/ambiguous -> CoerceArguments handles enum
var method = type.GetMethod("Equals", bindingFlags, null, types, null);
// Returns null or ambiguous

// NEW path: FindPublicMethodBySignature finds String.Equals(String, String)
// Invoking with ("linux", "StringComparison.InvariantCulture") returns false

We have not yet built the full new MSBuild and run it against runtime's project files to confirm end-to-end, so this analysis is based on code inspection and partial reproduction.

Affected Code

/cc @rainersigwald

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions