From 808cef9a1059fcf1a66d4b105a40106a7d463017 Mon Sep 17 00:00:00 2001 From: Yuriy Zatuchnyy Date: Wed, 14 Feb 2024 20:27:43 +0000 Subject: [PATCH] Analyzers/AnalyzerScope loops endlessly when analysing public inner class --- ILSpy.Tests/Analyzers/AnalyserScopeTests.cs | 52 +++++++++++++++++++++ ILSpy.Tests/ILSpy.Tests.csproj | 1 + ILSpy/Analyzers/AnalyzerScope.cs | 2 +- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 ILSpy.Tests/Analyzers/AnalyserScopeTests.cs diff --git a/ILSpy.Tests/Analyzers/AnalyserScopeTests.cs b/ILSpy.Tests/Analyzers/AnalyserScopeTests.cs new file mode 100644 index 00000000000..736e730d26f --- /dev/null +++ b/ILSpy.Tests/Analyzers/AnalyserScopeTests.cs @@ -0,0 +1,52 @@ +using System.Linq; +using System.Threading.Tasks; + +using ICSharpCode.Decompiler; +using ICSharpCode.Decompiler.CSharp.Resolver; +using ICSharpCode.Decompiler.Metadata; +using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.ILSpy.Analyzers; + +using Mono.Cecil; + +using NUnit.Framework; + +namespace ICSharpCode.ILSpy.Tests.Analyzers +{ + + [TestFixture] + public class AnalyzerScopeTests + { + public class TestClass + { + + } + + + [Test] + public void WhenPublicNestedClass_ThenNotInfiniteLoop() + { + // Given + ILSpyX.AssemblyList assemblyList = new ILSpyX.AssemblyList(); + var file = new PEFile(this.GetType().Assembly.Location); + var td = file.Metadata.TypeDefinitions.First(td => td.GetFullTypeName(file.Metadata).Name == nameof(TestClass)); + + Decompiler.Metadata.IAssemblyResolver assemblyResolver = new UniversalAssemblyResolver(null, false, null); + ICompilation compilation = new DecompilerTypeSystem(file, assemblyResolver); + ITypeResolveContext context = new CSharpResolver(compilation); + var module = ((IModuleReference)file).Resolve(context) as MetadataModule; + IEntity entity = module.GetDefinition(td); + + // When + var task = Task.Run(() => { + var target = new AnalyzerScope(assemblyList, entity); + }); + + var result = Task.WaitAny(new[] { task, Task.Delay(500) }); // 0.5 seconds + + // Then + Assert.That(result == 0, "The constructor should completes in no longer than 10 seconds"); + } + + } +} diff --git a/ILSpy.Tests/ILSpy.Tests.csproj b/ILSpy.Tests/ILSpy.Tests.csproj index 5bb3d121fba..ccd6f8f26f9 100644 --- a/ILSpy.Tests/ILSpy.Tests.csproj +++ b/ILSpy.Tests/ILSpy.Tests.csproj @@ -34,6 +34,7 @@ + diff --git a/ILSpy/Analyzers/AnalyzerScope.cs b/ILSpy/Analyzers/AnalyzerScope.cs index 4560ce535ed..fe844a33b96 100644 --- a/ILSpy/Analyzers/AnalyzerScope.cs +++ b/ILSpy/Analyzers/AnalyzerScope.cs @@ -122,7 +122,7 @@ static void DetermineEffectiveAccessibility(IEntity input, out ITypeDefinition t while (typeScope != null && !accessibility.LessThanOrEqual(Accessibility.Private)) { accessibility = accessibility.Intersect(typeScope.Accessibility); - typeScope = prevTypeScope.DeclaringTypeDefinition; + typeScope = typeScope.DeclaringTypeDefinition; } if (typeScope == null) {