From f1717a17f5147ca120f33b458d7855025153fdd2 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 18 Feb 2021 09:27:14 +0100 Subject: [PATCH] =?UTF-8?q?Fixes=20error=20trying=20to=20load=20Cosmos.CRT?= =?UTF-8?q?Compat.dll=20(System.BadImageForma=E2=80=A6=20(#9834)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bjarke Berg --- .../DefaultUmbracoAssemblyProvider.cs | 7 ++- .../FindAssembliesWithReferencesTo.cs | 8 +++- .../Composing/ReferenceResolver.cs | 47 ++++++++++++++----- .../TypeFinderBenchmarks.cs | 4 +- src/Umbraco.Tests.Common/TestHelperBase.cs | 2 +- .../Umbraco.Core/Composing/TypeFinderTests.cs | 5 +- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 2 +- .../UmbracoCoreServiceCollectionExtensions.cs | 2 +- src/Umbraco.Web/UmbracoApplicationBase.cs | 2 +- 9 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs index 3e0ea9c971..75039f19f3 100644 --- a/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs +++ b/src/Umbraco.Core/Composing/DefaultUmbracoAssemblyProvider.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using Microsoft.Extensions.Logging; namespace Umbraco.Core.Composing { @@ -14,6 +15,7 @@ namespace Umbraco.Core.Composing public class DefaultUmbracoAssemblyProvider : IAssemblyProvider { private readonly Assembly _entryPointAssembly; + private readonly ILoggerFactory _loggerFactory; private static readonly string[] UmbracoCoreAssemblyNames = new[] { "Umbraco.Core", @@ -26,9 +28,10 @@ namespace Umbraco.Core.Composing "Umbraco.Web.Website", }; - public DefaultUmbracoAssemblyProvider(Assembly entryPointAssembly) + public DefaultUmbracoAssemblyProvider(Assembly entryPointAssembly, ILoggerFactory loggerFactory) { _entryPointAssembly = entryPointAssembly ?? throw new ArgumentNullException(nameof(entryPointAssembly)); + _loggerFactory = loggerFactory; } // TODO: It would be worth investigating a netcore3 version of this which would use @@ -41,7 +44,7 @@ namespace Umbraco.Core.Composing { get { - var finder = new FindAssembliesWithReferencesTo(new[] { _entryPointAssembly }, UmbracoCoreAssemblyNames, true); + var finder = new FindAssembliesWithReferencesTo(new[] { _entryPointAssembly }, UmbracoCoreAssemblyNames, true, _loggerFactory); return finder.Find(); } } diff --git a/src/Umbraco.Core/Composing/FindAssembliesWithReferencesTo.cs b/src/Umbraco.Core/Composing/FindAssembliesWithReferencesTo.cs index 9378941166..eb6d784a96 100644 --- a/src/Umbraco.Core/Composing/FindAssembliesWithReferencesTo.cs +++ b/src/Umbraco.Core/Composing/FindAssembliesWithReferencesTo.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using Microsoft.Extensions.Logging; namespace Umbraco.Core.Composing { @@ -17,6 +18,7 @@ namespace Umbraco.Core.Composing private readonly Assembly[] _referenceAssemblies; private readonly string[] _targetAssemblies; private readonly bool _includeTargets; + private readonly ILoggerFactory _loggerFactory; /// /// Constructor @@ -24,11 +26,13 @@ namespace Umbraco.Core.Composing /// Entry point assemblies /// Used to check if the entry point or it's transitive assemblies reference these assembly names /// If true will also use the target assembly names as entry point assemblies - public FindAssembliesWithReferencesTo(Assembly[] referenceAssemblies, string[] targetAssemblyNames, bool includeTargets) + /// Logger factory for when scanning goes wrong + public FindAssembliesWithReferencesTo(Assembly[] referenceAssemblies, string[] targetAssemblyNames, bool includeTargets, ILoggerFactory loggerFactory) { _referenceAssemblies = referenceAssemblies; _targetAssemblies = targetAssemblyNames; _includeTargets = includeTargets; + _loggerFactory = loggerFactory; } public IEnumerable Find() @@ -54,7 +58,7 @@ namespace Umbraco.Core.Composing } } - var provider = new ReferenceResolver(_targetAssemblies, referenceItems); + var provider = new ReferenceResolver(_targetAssemblies, referenceItems, _loggerFactory.CreateLogger()); var assemblyNames = provider.ResolveAssemblies(); return assemblyNames.ToList(); } diff --git a/src/Umbraco.Core/Composing/ReferenceResolver.cs b/src/Umbraco.Core/Composing/ReferenceResolver.cs index 8c110dbeea..caa3ef8561 100644 --- a/src/Umbraco.Core/Composing/ReferenceResolver.cs +++ b/src/Umbraco.Core/Composing/ReferenceResolver.cs @@ -4,6 +4,8 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Security; +using Microsoft.Extensions.Logging; namespace Umbraco.Core.Composing { @@ -19,11 +21,12 @@ namespace Umbraco.Core.Composing private readonly IReadOnlyList _assemblies; private readonly Dictionary _classifications; private readonly List _lookup = new List(); - - public ReferenceResolver(IReadOnlyList targetAssemblies, IReadOnlyList entryPointAssemblies) + private readonly ILogger _logger; + public ReferenceResolver(IReadOnlyList targetAssemblies, IReadOnlyList entryPointAssemblies, ILogger logger) { _umbracoAssemblies = new HashSet(targetAssemblies, StringComparer.Ordinal); _assemblies = entryPointAssemblies; + _logger = logger; _classifications = new Dictionary(); foreach (var item in entryPointAssemblies) @@ -54,19 +57,39 @@ namespace Umbraco.Core.Composing { foreach(var dll in Directory.EnumerateFiles(dir, "*.dll")) { - var assemblyName = AssemblyName.GetAssemblyName(dll); + AssemblyName assemblyName = null; + try + { + assemblyName = AssemblyName.GetAssemblyName(dll); + } + catch (BadImageFormatException e) + { + _logger.LogDebug(e, "Could not load {dll} for type scanning, skipping", dll); + } + catch (SecurityException e) + { + _logger.LogError(e, "Could not access {dll} for type scanning due to a security problem", dll); + } + catch (Exception e) + { + _logger.LogInformation(e, "Error: could not load {dll} for type scanning", dll); + } - // don't include if this is excluded - if (TypeFinder.KnownAssemblyExclusionFilter.Any(f => assemblyName.FullName.StartsWith(f, StringComparison.InvariantCultureIgnoreCase))) - continue; + if (assemblyName != null) + { + // don't include if this is excluded + if (TypeFinder.KnownAssemblyExclusionFilter.Any(f => + assemblyName.FullName.StartsWith(f, StringComparison.InvariantCultureIgnoreCase))) + continue; - // don't include this item if it's Umbraco - // TODO: We should maybe pass an explicit list of these names in? - if (assemblyName.FullName.StartsWith("Umbraco.") || assemblyName.Name.EndsWith(".Views")) - continue; + // don't include this item if it's Umbraco + // TODO: We should maybe pass an explicit list of these names in? + if (assemblyName.FullName.StartsWith("Umbraco.") || assemblyName.Name.EndsWith(".Views")) + continue; - var assembly = Assembly.Load(assemblyName); - assemblies.Add(assembly); + var assembly = Assembly.Load(assemblyName); + assemblies.Add(assembly); + } } } diff --git a/src/Umbraco.Tests.Benchmarks/TypeFinderBenchmarks.cs b/src/Umbraco.Tests.Benchmarks/TypeFinderBenchmarks.cs index 203e19fc6e..35bfa29db1 100644 --- a/src/Umbraco.Tests.Benchmarks/TypeFinderBenchmarks.cs +++ b/src/Umbraco.Tests.Benchmarks/TypeFinderBenchmarks.cs @@ -16,14 +16,14 @@ namespace Umbraco.Tests.Benchmarks [Benchmark(Baseline = true)] public void WithGetReferencingAssembliesCheck() { - var typeFinder1 = new TypeFinder(new NullLogger(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash()); + var typeFinder1 = new TypeFinder(new NullLogger(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash()); var found = typeFinder1.FindClassesOfType().Count(); } [Benchmark] public void WithoutGetReferencingAssembliesCheck() { - var typeFinder2 = new TypeFinder(new NullLogger(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash()); + var typeFinder2 = new TypeFinder(new NullLogger(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash()); typeFinder2.QueryWithReferencingAssemblies = false; var found = typeFinder2.FindClassesOfType().Count(); } diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index b7ad1e7f52..732c9df5c2 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -41,7 +41,7 @@ namespace Umbraco.Tests.Common protected TestHelperBase(Assembly entryAssembly) { MainDom = new SimpleMainDom(); - _typeFinder = new TypeFinder(NullLoggerFactory.Instance.CreateLogger(), new DefaultUmbracoAssemblyProvider(entryAssembly), new VaryingRuntimeHash()); + _typeFinder = new TypeFinder(NullLoggerFactory.Instance.CreateLogger(), new DefaultUmbracoAssemblyProvider(entryAssembly, NullLoggerFactory.Instance), new VaryingRuntimeHash()); } public ITypeFinder GetTypeFinder() => _typeFinder; diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeFinderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeFinderTests.cs index 1becc88138..a33096007c 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeFinderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/TypeFinderTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Moq; using NUnit.Framework; using Umbraco.Core.Composing; @@ -38,7 +39,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing [Test] public void Find_Class_Of_Type_With_Attribute() { - var typeFinder = new TypeFinder(Mock.Of>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash()); + var typeFinder = new TypeFinder(Mock.Of>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash()); IEnumerable typesFound = typeFinder.FindClassesOfTypeWithAttribute(_assemblies); Assert.AreEqual(2, typesFound.Count()); } @@ -46,7 +47,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing [Test] public void Find_Classes_With_Attribute() { - var typeFinder = new TypeFinder(Mock.Of>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash()); + var typeFinder = new TypeFinder(Mock.Of>(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, NullLoggerFactory.Instance), new VaryingRuntimeHash()); IEnumerable typesFound = typeFinder.FindClassesWithAttribute(_assemblies); Assert.AreEqual(0, typesFound.Count()); // 0 classes in _assemblies are marked with [Tree] diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index c306451f66..0888bafa97 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -191,7 +191,7 @@ namespace Umbraco.Tests.Testing var proflogger = new ProfilingLogger(loggerFactory.CreateLogger(), profiler); IOHelper = TestHelper.IOHelper; - TypeFinder = new TypeFinder(loggerFactory.CreateLogger(), new DefaultUmbracoAssemblyProvider(GetType().Assembly), new VaryingRuntimeHash()); + TypeFinder = new TypeFinder(loggerFactory.CreateLogger(), new DefaultUmbracoAssemblyProvider(GetType().Assembly, loggerFactory), new VaryingRuntimeHash()); var appCaches = GetAppCaches(); var globalSettings = new GlobalSettings(); var settings = new WebRoutingSettings(); diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs index 4161cafd91..e6617dfc73 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs @@ -81,7 +81,7 @@ namespace Umbraco.Extensions var typeFinder = new TypeFinder( loggerFactory.CreateLogger(), - new DefaultUmbracoAssemblyProvider(entryAssembly), + new DefaultUmbracoAssemblyProvider(entryAssembly, loggerFactory), runtimeHash, new TypeFinderConfig(Options.Create(typeFinderSettings)) ); diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index 82182e26b7..67e1c323d9 100644 --- a/src/Umbraco.Web/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -119,7 +119,7 @@ namespace Umbraco.Web // assembly we can get and we can only get that if we put this code into the WebRuntime since the executing assembly is the 'current' one. // For this purpose, it doesn't matter if it's Umbraco.Web or Umbraco.Infrastructure since all assemblies are in that same path and we are // getting rid of netframework. - Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly()), runtimeHash); + Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(), _loggerFactory), runtimeHash); } ///