-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update SignatureComparer.TypeDefOrRef.cs #319
Conversation
Thanks for spotting the issue, however I don't think this is the right solution that tackles the problem at its core. First, in the case of a type being nested, the I believe the problem exists because the tests after the Also, this would probably need a unit test before it should be merged. |
I have made another update hopefully it is better solution now. It is working for me well now. There was another problem where System.Type is not equal to another System.Type because somewhere else in the code Culture is initialised with null and Utf8string.Empty != null In order to prevent nested types being compared as equal i have added additional check for last pass to check if modules are the same before trying to resolve() and compare again |
It might be, but we should add a representative unit test so that this doesn't happen again in the future after someone makes another change.
This is a separate issue and will need another unit test that represents this exact case.
I am not sure why we would want to prevent nested types being compared? We would probably want to recursively test whether the declaring types are matching, to support arbitrary amounts of nesting. |
I think what is missing is a call What do you think? |
I have added test code which will fail with current comparer code. |
I believe your solution still does not tackle the problem at its core. Without testing for the declaring type itself, we still have a nasty edge case with nested types that are forwarded / exported. In this case, it is possible that See below for test-case: ActualLibrary.il
ForwarderLibrary.il
Main.il
Compile using:
Then test using code: [Fact]
public void MatchForwardedNestedTypes()
{
var module = ModuleDefinition.FromFile("/tmp/test/Main.exe");
var referencedTypes = module.ManagedEntrypointMethod!.CilMethodBody!.Instructions
.Where(i => i.OpCode.Code == CilCode.Call)
.Select(i=> ((IMethodDefOrRef) i.Operand!).DeclaringType)
.ToArray();
var type1 = referencedTypes[0]!;
var type2 = referencedTypes[1]!;
var resolvedType1 = type1.Resolve();
var resolvedType2 = type2.Resolve();
Assert.Equal(type1, resolvedType1, _comparer);
Assert.Equal(type2, resolvedType2, _comparer);
Assert.NotEqual(type1, type2, _comparer);
Assert.NotEqual(type1, resolvedType2, _comparer); // Fails
Assert.NotEqual(type2, resolvedType1, _comparer); // Fails
} |
Please check the update |
Yes this seems to solve the problem, the edge case passes now just fine. I will merge this and include it in hotfix 4.11.1 that I have planned to push in the next day or two. Thanks again for spotting the bug! |
Comparing by namespace is not enough, need to compare by declaring type too, because namespace can be null which way it leads to situation where two nested different types with same name can be compared as equal