From 41ac88e70429b780e4a46a4d209fb23d715a4308 Mon Sep 17 00:00:00 2001 From: Martin Karing Date: Sat, 24 Apr 2021 17:11:31 +0200 Subject: [PATCH] Fixed VTable analyzer for fully inherited slots (#342) --- Confuser.Renamer/Analyzers/VTableAnalyzer.cs | 17 ++++++++- Confuser.Renamer/VTable.cs | 18 ++-------- Confuser2.sln | 36 +++++++++++++++++-- .../342_InterfaceRenamingLoop.Test.csproj | 14 ++++++++ .../InterfaceRenamingLoopTest.cs | 35 ++++++++++++++++++ .../342_InterfaceRenamingLoop.csproj | 10 ++++++ Tests/342_InterfaceRenamingLoop/CBase.cs | 7 ++++ Tests/342_InterfaceRenamingLoop/ClassA.cs | 10 ++++++ Tests/342_InterfaceRenamingLoop/ClassB.cs | 10 ++++++ Tests/342_InterfaceRenamingLoop/IAEvents.cs | 6 ++++ Tests/342_InterfaceRenamingLoop/Program.cs | 16 +++++++++ 11 files changed, 160 insertions(+), 19 deletions(-) create mode 100644 Tests/342_InterfaceRenamingLoop.Test/342_InterfaceRenamingLoop.Test.csproj create mode 100644 Tests/342_InterfaceRenamingLoop.Test/InterfaceRenamingLoopTest.cs create mode 100644 Tests/342_InterfaceRenamingLoop/342_InterfaceRenamingLoop.csproj create mode 100644 Tests/342_InterfaceRenamingLoop/CBase.cs create mode 100644 Tests/342_InterfaceRenamingLoop/ClassA.cs create mode 100644 Tests/342_InterfaceRenamingLoop/ClassB.cs create mode 100644 Tests/342_InterfaceRenamingLoop/IAEvents.cs create mode 100644 Tests/342_InterfaceRenamingLoop/Program.cs diff --git a/Confuser.Renamer/Analyzers/VTableAnalyzer.cs b/Confuser.Renamer/Analyzers/VTableAnalyzer.cs index 60ccd3963..7555407b5 100644 --- a/Confuser.Renamer/Analyzers/VTableAnalyzer.cs +++ b/Confuser.Renamer/Analyzers/VTableAnalyzer.cs @@ -306,7 +306,22 @@ private static void SetupOverwriteReferences(INameService service, ICollection(); - InterfaceSlots = new Dictionary>(); + InterfaceSlots = new Dictionary>(TypeEqualityComparer.Instance); } public TypeSig Type { get; private set; } @@ -107,23 +107,11 @@ internal VTable(TypeSig type) { public IDictionary> InterfaceSlots { get; private set; } class VTableConstruction { - class TypeSigComparer : IEqualityComparer { - public bool Equals(TypeSig x, TypeSig y) { - return new SigComparer().Equals(x, y); - } - - public int GetHashCode(TypeSig obj) { - return new SigComparer().GetHashCode(obj); - } - - public static readonly TypeSigComparer Instance = new TypeSigComparer(); - } - // All virtual method slots, excluding interfaces public List AllSlots = new List(); // All visible virtual method slots (i.e. excluded those being shadowed) public Dictionary SlotsMap = new Dictionary(); - public Dictionary> InterfaceSlots = new Dictionary>(TypeSigComparer.Instance); + public Dictionary> InterfaceSlots = new Dictionary>(TypeEqualityComparer.Instance); } public IEnumerable FindSlots(IMethod method) { @@ -252,7 +240,7 @@ public static VTable ConstructVTable(TypeDef typeDef, VTableStorage storage) { // Populate result V-table ret.InterfaceSlots = vTbl.InterfaceSlots.ToDictionary( - kvp => kvp.Key, kvp => (IList)kvp.Value.SelectMany(g => g).ToList()); + kvp => kvp.Key, kvp => (IList)kvp.Value.SelectMany(g => g).ToList(), TypeEqualityComparer.Instance); foreach (var slot in vTbl.AllSlots) { ret.Slots.Add(slot); diff --git a/Confuser2.sln b/Confuser2.sln index 57d096214..064dd0d0d 100644 --- a/Confuser2.sln +++ b/Confuser2.sln @@ -111,11 +111,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "244_ClrProtection", "Tests\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "244_ClrProtection.Test", "Tests\244_ClrProtection.Test\244_ClrProtection.Test.csproj", "{3ADB8BB1-AE14-49DA-A7E1-1C0D9BEB76E9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "306_ComplexClassStructureRename.Lib", "Tests\306_ComplexClassStructureRename.Lib\306_ComplexClassStructureRename.Lib.csproj", "{FD93D181-2EC5-4863-8A8F-5F8C84C06B35}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "306_ComplexClassStructureRename.Lib", "Tests\306_ComplexClassStructureRename.Lib\306_ComplexClassStructureRename.Lib.csproj", "{FD93D181-2EC5-4863-8A8F-5F8C84C06B35}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "306_ComplexClassStructureRename", "Tests\306_ComplexClassStructureRename\306_ComplexClassStructureRename.csproj", "{1B52A3D9-014C-4CBF-BB98-09080D9A8D16}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "306_ComplexClassStructureRename", "Tests\306_ComplexClassStructureRename\306_ComplexClassStructureRename.csproj", "{1B52A3D9-014C-4CBF-BB98-09080D9A8D16}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "306_ComplexClassStructureRename.Test", "Tests\306_ComplexClassStructureRename.Test\306_ComplexClassStructureRename.Test.csproj", "{13431429-2DB6-480F-B73F-CA019FE759E3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "306_ComplexClassStructureRename.Test", "Tests\306_ComplexClassStructureRename.Test\306_ComplexClassStructureRename.Test.csproj", "{13431429-2DB6-480F-B73F-CA019FE759E3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "342_InterfaceRenamingLoop", "Tests\342_InterfaceRenamingLoop\342_InterfaceRenamingLoop.csproj", "{382B6332-4A57-458D-96EB-B312688A7604}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "342_InterfaceRenamingLoop.Test", "Tests\342_InterfaceRenamingLoop.Test\342_InterfaceRenamingLoop.Test.csproj", "{EC62CE1D-ADD7-419A-84A9-D6A04E866197}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -727,6 +731,30 @@ Global {13431429-2DB6-480F-B73F-CA019FE759E3}.Release|x64.Build.0 = Release|Any CPU {13431429-2DB6-480F-B73F-CA019FE759E3}.Release|x86.ActiveCfg = Release|Any CPU {13431429-2DB6-480F-B73F-CA019FE759E3}.Release|x86.Build.0 = Release|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Debug|Any CPU.Build.0 = Debug|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Debug|x64.ActiveCfg = Debug|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Debug|x64.Build.0 = Debug|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Debug|x86.ActiveCfg = Debug|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Debug|x86.Build.0 = Debug|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Release|Any CPU.ActiveCfg = Release|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Release|Any CPU.Build.0 = Release|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Release|x64.ActiveCfg = Release|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Release|x64.Build.0 = Release|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Release|x86.ActiveCfg = Release|Any CPU + {382B6332-4A57-458D-96EB-B312688A7604}.Release|x86.Build.0 = Release|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Debug|x64.ActiveCfg = Debug|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Debug|x64.Build.0 = Debug|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Debug|x86.ActiveCfg = Debug|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Debug|x86.Build.0 = Debug|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Release|Any CPU.Build.0 = Release|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Release|x64.ActiveCfg = Release|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Release|x64.Build.0 = Release|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Release|x86.ActiveCfg = Release|Any CPU + {EC62CE1D-ADD7-419A-84A9-D6A04E866197}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -774,6 +802,8 @@ Global {FD93D181-2EC5-4863-8A8F-5F8C84C06B35} = {356BDB31-853E-43BB-8F9A-D8AC08F69EBB} {1B52A3D9-014C-4CBF-BB98-09080D9A8D16} = {356BDB31-853E-43BB-8F9A-D8AC08F69EBB} {13431429-2DB6-480F-B73F-CA019FE759E3} = {356BDB31-853E-43BB-8F9A-D8AC08F69EBB} + {382B6332-4A57-458D-96EB-B312688A7604} = {356BDB31-853E-43BB-8F9A-D8AC08F69EBB} + {EC62CE1D-ADD7-419A-84A9-D6A04E866197} = {356BDB31-853E-43BB-8F9A-D8AC08F69EBB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0D937D9E-E04B-4A68-B639-D4260473A388} diff --git a/Tests/342_InterfaceRenamingLoop.Test/342_InterfaceRenamingLoop.Test.csproj b/Tests/342_InterfaceRenamingLoop.Test/342_InterfaceRenamingLoop.Test.csproj new file mode 100644 index 000000000..e945936c9 --- /dev/null +++ b/Tests/342_InterfaceRenamingLoop.Test/342_InterfaceRenamingLoop.Test.csproj @@ -0,0 +1,14 @@ + + + + net461 + InterfaceRenamingLoop.Test + false + + + + + + + + diff --git a/Tests/342_InterfaceRenamingLoop.Test/InterfaceRenamingLoopTest.cs b/Tests/342_InterfaceRenamingLoop.Test/InterfaceRenamingLoopTest.cs new file mode 100644 index 000000000..04b31cece --- /dev/null +++ b/Tests/342_InterfaceRenamingLoop.Test/InterfaceRenamingLoopTest.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Confuser.Core; +using Confuser.Core.Project; +using Confuser.Renamer; +using Confuser.UnitTest; +using Xunit; +using Xunit.Abstractions; + +namespace InterfaceRenamingLoop.Test { + public class InterfaceRenamingLoopTest : TestBase { + public InterfaceRenamingLoopTest(ITestOutputHelper outputHelper) : base(outputHelper) { } + + [Theory] + [MemberData(nameof(RenameInterfaceLoopTestData))] + [Trait("Category", "Protection")] + [Trait("Protection", "rename")] + [Trait("Issue", "https://github.com/mkaring/ConfuserEx/issues/342")] + public async Task RenameInterfaceLoop(string renameMode) => + await Run( + "342_InterfaceRenamingLoop.exe", + Array.Empty(), + new SettingItem("rename") { + { "mode", renameMode } + }, + $"_{renameMode}" + ); + + public static IEnumerable RenameInterfaceLoopTestData() { + foreach (var renameMode in new[] { nameof(RenameMode.Unicode), nameof(RenameMode.Debug), nameof(RenameMode.Sequential) }) + yield return new object[] { renameMode }; + } + } +} diff --git a/Tests/342_InterfaceRenamingLoop/342_InterfaceRenamingLoop.csproj b/Tests/342_InterfaceRenamingLoop/342_InterfaceRenamingLoop.csproj new file mode 100644 index 000000000..ce1bd2a1e --- /dev/null +++ b/Tests/342_InterfaceRenamingLoop/342_InterfaceRenamingLoop.csproj @@ -0,0 +1,10 @@ + + + + Exe + net461 + InterfaceRenamingLoop + InterfaceRenamingLoop.Program + + + diff --git a/Tests/342_InterfaceRenamingLoop/CBase.cs b/Tests/342_InterfaceRenamingLoop/CBase.cs new file mode 100644 index 000000000..4cb11d3a8 --- /dev/null +++ b/Tests/342_InterfaceRenamingLoop/CBase.cs @@ -0,0 +1,7 @@ +namespace InterfaceRenamingLoop { + internal class CBase { + public virtual void TestEvent(int code, string description) { + + } + } +} diff --git a/Tests/342_InterfaceRenamingLoop/ClassA.cs b/Tests/342_InterfaceRenamingLoop/ClassA.cs new file mode 100644 index 000000000..1bd04a97d --- /dev/null +++ b/Tests/342_InterfaceRenamingLoop/ClassA.cs @@ -0,0 +1,10 @@ +namespace InterfaceRenamingLoop { + internal class ClassA : CBase, IAEvents { + public void TestA(int errorCode) { + + } + public override void TestEvent(int code, string description) { + + } + } +} diff --git a/Tests/342_InterfaceRenamingLoop/ClassB.cs b/Tests/342_InterfaceRenamingLoop/ClassB.cs new file mode 100644 index 000000000..4e92c34c9 --- /dev/null +++ b/Tests/342_InterfaceRenamingLoop/ClassB.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace InterfaceRenamingLoop { + internal class ClassB : ClassA { + } +} diff --git a/Tests/342_InterfaceRenamingLoop/IAEvents.cs b/Tests/342_InterfaceRenamingLoop/IAEvents.cs new file mode 100644 index 000000000..3ce48b786 --- /dev/null +++ b/Tests/342_InterfaceRenamingLoop/IAEvents.cs @@ -0,0 +1,6 @@ +namespace InterfaceRenamingLoop { + internal interface IAEvents { + void TestA(int errorCode); + void TestEvent(int errorCode, string description); + } +} diff --git a/Tests/342_InterfaceRenamingLoop/Program.cs b/Tests/342_InterfaceRenamingLoop/Program.cs new file mode 100644 index 000000000..bb96b141d --- /dev/null +++ b/Tests/342_InterfaceRenamingLoop/Program.cs @@ -0,0 +1,16 @@ +using System; + +namespace InterfaceRenamingLoop { + public class Program { + internal static int Main(string[] args) { + Console.WriteLine("START"); + + var test = new ClassB(); + test.TestEvent(0, "TEST"); + + Console.WriteLine("END"); + + return 42; + } + } +}