From b6da9b23b14f0f7412bcf6b9309139b2a8859166 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 28 Mar 2021 23:40:20 +0200 Subject: [PATCH] Fix thread-safety issue in UniversalAssemblyResolver --- .../Metadata/UniversalAssemblyResolver.cs | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs b/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs index 49d803e12..cc32ba8f2 100644 --- a/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs +++ b/ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs @@ -60,7 +60,7 @@ namespace ICSharpCode.Decompiler.Metadata decompilerRuntime = DecompilerRuntime.Mono; } - DotNetCorePathFinder dotNetCorePathFinder; + readonly Lazy dotNetCorePathFinder; readonly bool throwOnError; readonly PEStreamOptions streamOptions; readonly MetadataReaderOptions metadataOptions; @@ -73,13 +73,19 @@ namespace ICSharpCode.Decompiler.Metadata public void AddSearchDirectory(string directory) { directories.Add(directory); - dotNetCorePathFinder?.AddSearchDirectory(directory); + if (dotNetCorePathFinder.IsValueCreated) + { + dotNetCorePathFinder.Value.AddSearchDirectory(directory); + } } public void RemoveSearchDirectory(string directory) { directories.Remove(directory); - dotNetCorePathFinder?.RemoveSearchDirectory(directory); + if (dotNetCorePathFinder.IsValueCreated) + { + dotNetCorePathFinder.Value.RemoveSearchDirectory(directory); + } } public string[] GetSearchDirectories() @@ -125,7 +131,7 @@ namespace ICSharpCode.Decompiler.Metadata this.targetFramework = targetFramework ?? string.Empty; this.runtimePack = runtimePack ?? "Microsoft.NETCore.App"; (targetFrameworkIdentifier, targetFrameworkVersion) = ParseTargetFramework(this.targetFramework); - + this.dotNetCorePathFinder = new Lazy(InitDotNetCorePathFinder); if (mainAssemblyFileName != null) { string baseDirectory = Path.GetDirectoryName(mainAssemblyFileName); @@ -223,7 +229,7 @@ namespace ICSharpCode.Decompiler.Metadata public override bool IsSharedAssembly(IAssemblyReference reference, out string runtimePack) { - return dotNetCorePathFinder.TryResolveDotNetCoreShared(reference, out runtimePack) != null; + return dotNetCorePathFinder.Value.TryResolveDotNetCoreShared(reference, out runtimePack) != null; } public string FindAssemblyFile(IAssemblyReference name) @@ -240,18 +246,7 @@ namespace ICSharpCode.Decompiler.Metadata case TargetFrameworkIdentifier.NETStandard: if (IsZeroOrAllOnes(targetFrameworkVersion)) goto default; - if (dotNetCorePathFinder == null) - { - if (mainAssemblyFileName == null) - dotNetCorePathFinder = new DotNetCorePathFinder(targetFrameworkIdentifier, targetFrameworkVersion, runtimePack); - else - dotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, targetFramework, runtimePack, targetFrameworkIdentifier, targetFrameworkVersion); - foreach (var directory in directories) - { - dotNetCorePathFinder.AddSearchDirectory(directory); - } - } - file = dotNetCorePathFinder.TryResolveDotNetCore(name); + file = dotNetCorePathFinder.Value.TryResolveDotNetCore(name); if (file != null) return file; goto default; @@ -267,6 +262,20 @@ namespace ICSharpCode.Decompiler.Metadata } } + DotNetCorePathFinder InitDotNetCorePathFinder() + { + DotNetCorePathFinder dotNetCorePathFinder; + if (mainAssemblyFileName == null) + dotNetCorePathFinder = new DotNetCorePathFinder(targetFrameworkIdentifier, targetFrameworkVersion, runtimePack); + else + dotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, targetFramework, runtimePack, targetFrameworkIdentifier, targetFrameworkVersion); + foreach (var directory in directories) + { + dotNetCorePathFinder.AddSearchDirectory(directory); + } + return dotNetCorePathFinder; + } + string FindWindowsMetadataFile(IAssemblyReference name) { // Finding Windows Metadata (winmd) is currently only supported on Windows.