public static void LoadFromStreamNull() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { Assert.Throws <ArgumentNullException>(() => lc.LoadFromStream(null)); } }
private Version GetBinaryVersion(MetadataLoadContext metaDataLoadContext, IArchiveEntry archiveEntry) { using var entryStream = archiveEntry.ExtractToStream(); var assembly = metaDataLoadContext.LoadFromStream(entryStream); return(assembly.GetName().Version); }
/// <exception cref="ArgumentNullException">Throws exception if Name property of assemblyName is null</exception> /// <inheritdoc /> public override Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName) { Assembly candidateWithSamePkt = null; Assembly candidateIgnoringPkt = null; if (assemblyName == null) { throw new ArgumentNullException(nameof(assemblyName)); } if (assemblyName.Name == null) { throw new ArgumentNullException(nameof(assemblyName.Name)); } if (_zipEntries.TryGetValue(assemblyName.Name, out List <IArchiveEntry> archiveEntries)) { ReadOnlySpan <byte> pktFromName = assemblyName.GetPublicKeyToken(); foreach (var archiveEntry in archiveEntries) { using var entryStream = archiveEntry.ExtractToStream(); var assemblyFromZip = context.LoadFromStream(entryStream); var assemblyNameFromZip = assemblyFromZip.GetName(); if (assemblyName.Name != null && assemblyName.Name.Equals(assemblyNameFromZip.Name, StringComparison.OrdinalIgnoreCase)) { ReadOnlySpan <byte> pktFromAssembly = assemblyNameFromZip.GetPublicKeyToken(); // Find exact match on PublicKeyToken including treating no PublicKeyToken as its own entry. if (pktFromName.SequenceEqual(pktFromAssembly)) { // Pick the highest version. if (candidateWithSamePkt == null || assemblyNameFromZip.Version > candidateWithSamePkt.GetName().Version) { candidateWithSamePkt = assemblyFromZip; } } // If assemblyName does not specify a PublicKeyToken, then still consider those with a PublicKeyToken. else if (candidateWithSamePkt == null && pktFromName.IsEmpty) { // Pick the highest version. if (candidateIgnoringPkt == null || assemblyNameFromZip.Version > candidateIgnoringPkt.GetName().Version) { candidateIgnoringPkt = assemblyFromZip; } } } } } var assembly = candidateWithSamePkt ?? candidateIgnoringPkt; if (assemblyName.Name != null && (assembly == null) && (assemblyName.Name.Equals(_coreAssemblyName, StringComparison.InvariantCultureIgnoreCase))) { assembly = context.LoadFromAssemblyPath(_coreAssemblyPath); } return(assembly); }
public static void AssemblyDefinedTypeInfosReturnsDifferentObjectsEachTime() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { Assembly a = lc.LoadFromStream(TestUtils.CreateStreamForCoreAssembly()); TestUtils.AssertNewObjectReturnedEachTime <TypeInfo>(() => a.DefinedTypes); } }
private (Stream AssemblyStream, Assembly Assembly, MethodInfo[] DecoratedMethods, string AssemblyPath, string[] AliasCategories) FindAssemblyToAnalyze(IPackageCoreReader package, string[] assembliesPath) { foreach (var assemblyPath in assembliesPath) { var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"); // The assembly resolver makes the assemblies referenced by THIS APPLICATION (i.e.: the AddinDiscoverer) available // for resolving types when looping through custom attributes. As of this writing, there is one addin written in // FSharp which was causing 'Could not find FSharp.Core' when looping through its custom attributes. To solve this // problem, I added a reference to FSharp.Core in Cake.AddinDiscoverer.csproj var assemblyResolver = new PathAssemblyResolver(runtimeAssemblies); // It's important to create a new load context for each assembly to ensure one addin does not interfere with another var loadContext = new MetadataLoadContext(assemblyResolver); // Load the assembly var assemblyStream = LoadFileFromPackage(package, assemblyPath); var assembly = loadContext.LoadFromStream(assemblyStream); var isModule = assembly .CustomAttributes .Any(a => a.AttributeType.Namespace == "Cake.Core.Annotations" && a.AttributeType.Name == "CakeModuleAttribute"); // Search for decorated methods. // Please note that it's important to use the '.ExportedTypes' and the '.CustomAttributes' properties rather than // the '.GetExportedTypes' and the '.GetCustomAttributes' methods because the latter will instantiate the custom // attributes which, in our case, will cause exceptions because they are defined in dependencies which are most // likely not available in the load context. var decoratedMethods = assembly .ExportedTypes .SelectMany(type => type.GetTypeInfo().DeclaredMethods) .Where(method => method.CustomAttributes.Any(a => a.AttributeType.Namespace == "Cake.Core.Annotations" && (a.AttributeType.Name == "CakeMethodAliasAttribute" || a.AttributeType.Name == "CakePropertyAliasAttribute"))) .ToArray(); // Search for alias categories var aliasCategories = assembly .ExportedTypes .SelectMany(t => t.CustomAttributes) .Where(a => a.AttributeType.Namespace == "Cake.Core.Annotations" && a.AttributeType.Name == "CakeAliasCategoryAttribute") .Select(a => a.ConstructorArguments[0].Value?.ToString()) .Where(category => !string.IsNullOrEmpty(category)) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray(); if (isModule || decoratedMethods.Any()) { return(assemblyStream, assembly, decoratedMethods, assemblyPath, aliasCategories); } } return(null, null, Array.Empty <MethodInfo>(), string.Empty, Array.Empty <string>()); }
public static void BadImageFormat() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { for (int i = 0; i < 100; i++) { Stream s = new MemoryStream(new byte[i]); Assert.Throws <BadImageFormatException>(() => lc.LoadFromStream(s)); } } }
/// <summary> /// Determines if the package contains a 32-bit executable. /// </summary> /// <param name="package">The package to examine if it contains a 32-bit executable.</param> /// <returns><c>true</c> if the package contains a 32-bit executable, <c>false</c> otherwise.</returns> private (bool contains32BitExecutable, string assemblyName) DoesPackageContain32bitExecutable(Package package) { var coreAssembly = typeof(object).Assembly; using var byteStream = new MemoryStream(package.Content); using var archive = ArchiveFactory.Open(byteStream); using var lc = new MetadataLoadContext(new ZipAssemblyResolver(archive, coreAssembly), coreAssembly.FullName); { foreach (var archiveEntry in archive.Entries) { if (archiveEntry.IsDirectory) { continue; } if (archiveEntry.Key.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase)) { using var entryStream = archiveEntry.ExtractToStream(); try { var assembly = lc.LoadFromStream(entryStream); foreach (var module in assembly.GetModules()) { module.GetPEKind(out var peKind, out _); if (peKind.HasFlag(PortableExecutableKinds.Preferred32Bit) || peKind.HasFlag(PortableExecutableKinds.Required32Bit)) { return(true, archiveEntry.Key); } } } catch (BadImageFormatException) { Logger.LogDebug($"{package} - {archiveEntry.Key} - {nameof(BadImageFormatException)}."); } catch (FileLoadException) { Logger.LogError($"{package} - {archiveEntry.Key} - could not be loaded."); } catch (Exception e) { Logger.LogError(e, $"{package} - {archiveEntry.Key} - threw an exception."); } } } } return(false, string.Empty); }
public static void MetadataLoadContextApisAfterDispose() { MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver()); lc.Dispose(); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromAssemblyName(new AssemblyName("Foo"))); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromAssemblyName("Foo")); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromAssemblyPath("Foo")); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromByteArray(TestData.s_SimpleAssemblyImage)); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromStream(new MemoryStream(TestData.s_SimpleAssemblyImage))); Assert.Throws <ObjectDisposedException>(() => lc.CoreAssembly); Assert.Throws <ObjectDisposedException>(() => lc.GetAssemblies()); }
public static void LoadFromAssemblyName() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { Stream peStream = new MemoryStream(TestData.s_SimpleAssemblyImage); Assembly a = lc.LoadFromStream(peStream); Assert.NotNull(a); Assembly a1 = lc.LoadFromAssemblyName(TestData.s_SimpleAssemblyName); Assert.Equal(a, a1); Assembly a2 = lc.LoadFromAssemblyName(new AssemblyName(TestData.s_SimpleAssemblyName)); Assert.Equal(a, a2); } }
public static void LoadFromAssemblyName() { // Note this is using SimpleAssemblyResolver in order to resolve LoadFromAssemblyName. using (MetadataLoadContext lc = new MetadataLoadContext(new SimpleAssemblyResolver())) { Stream peStream = new MemoryStream(TestData.s_SimpleAssemblyImage); Assembly a = lc.LoadFromStream(peStream); Assert.NotNull(a); Assembly a1 = lc.LoadFromAssemblyName(TestData.s_SimpleAssemblyFullName); Assert.Equal(a, a1); Assembly a2 = lc.LoadFromAssemblyName(new AssemblyName(TestData.s_SimpleAssemblyFullName)); Assert.Equal(a, a2); } }
public static void LoadFromStreamMemorySimpleAssembly() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { Stream peStream = new MemoryStream(TestData.s_SimpleAssemblyImage); Assembly a = lc.LoadFromStream(peStream); Assert.NotNull(a); string fullName = a.GetName().FullName; Assert.Equal(TestData.s_SimpleAssemblyFullName, fullName); Guid mvid = a.ManifestModule.ModuleVersionId; Assert.Equal(TestData.s_SimpleAssemblyMvid, mvid); Assert.Equal(string.Empty, a.Location); } }
public static void LoadFromNonZeroPositionedStreamMemorySimpleAssembly() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { Stream peStream = new MemoryStream(TestData.s_SimpleAssemblyImage); peStream.Position = 1; // The MetadataLoadContext takes ownership of the peStream. It will reset its position back to 0. Assembly a = lc.LoadFromStream(peStream); Assert.NotNull(a); string fullName = a.GetName().FullName; Assert.Equal(TestData.s_SimpleAssemblyFullName, fullName); Guid mvid = a.ManifestModule.ModuleVersionId; Assert.Equal(TestData.s_SimpleAssemblyMvid, mvid); Assert.Equal(string.Empty, a.Location); } }
public static void LoadFromStreamFileSimpleAssembly() { using (TempFile tf = TempFile.Create(TestData.s_SimpleAssemblyImage)) { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { Stream fs = File.OpenRead(tf.Path); Assembly a = lc.LoadFromStream(fs); Assert.NotNull(a); string fullName = a.GetName().FullName; Assert.Equal(TestData.s_SimpleAssemblyFullName, fullName); Guid mvid = a.ManifestModule.ModuleVersionId; Assert.Equal(TestData.s_SimpleAssemblyMvid, mvid); Assert.Equal(tf.Path, a.Location); } } }
public override Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName) { string name = assemblyName.Name; if (name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase) || name.Equals("System.Private.CoreLib", StringComparison.OrdinalIgnoreCase) || name.Equals("System.Runtime", StringComparison.OrdinalIgnoreCase) || name.Equals("netstandard", StringComparison.OrdinalIgnoreCase) || // For interop attributes such as DllImport and Guid: name.Equals("System.Runtime.InteropServices", StringComparison.OrdinalIgnoreCase)) { if (_coreAssembly == null) { _coreAssembly = context.LoadFromStream(TestUtils.CreateStreamForCoreAssembly()); } return(_coreAssembly); } return(null); }
private void PopulatePackageAssembliesFromPackageContent(Package package, Entity.Package packageEntity, PackageVersion packageVersionEntity) { var uniqueAssemblies = new Dictionary <string, AssemblyName>(); var coreAssembly = typeof(object).Assembly; using var byteStream = new MemoryStream(package.Content); using var archive = ArchiveFactory.Open(byteStream); using var lc = new MetadataLoadContext(new ZipAssemblyResolver(archive, coreAssembly), coreAssembly.FullName); foreach (var archiveEntry in archive.Entries) { if (archiveEntry.IsDirectory || (!archiveEntry.Key.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase) && !archiveEntry.Key.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))) { continue; } System.Reflection.Assembly assembly; using var entryStream = archiveEntry.ExtractToStream(); try { assembly = lc.LoadFromStream(entryStream); } catch (FileLoadException) { Logger.LogError($"{packageEntity.Name} (v{packageVersionEntity.Version}) - {archiveEntry.Key} - could not be loaded."); continue; } catch (Exception e) { Logger.LogError(e, $"{packageEntity.Name} (v{packageVersionEntity.Version}) - {archiveEntry.Key} - threw an exception."); continue; } foreach (var referencedAssembly in assembly.GetReferencedAssemblies()) { if (!uniqueAssemblies.ContainsKey(referencedAssembly.FullName)) { uniqueAssemblies.Add(referencedAssembly.FullName, referencedAssembly); } } var assemblyName = assembly.GetName(); Logger.LogDebug($"Processing assembly {assemblyName.Name}, version={assemblyName.Version}"); var assemblyEntity = GetOrAddAssemblyEntity(assemblyName); var assemblyVersionEntity = GetOrAddAssemblyVersionEntity(assemblyEntity, assemblyName); var packageAssemblyVersionEntity = GetOrAddPackageAssemblyVersionEntity(packageEntity, packageVersionEntity, assemblyEntity, assemblyVersionEntity); packageAssemblyVersionEntity.ReferenceIncluded = true; } foreach (var uniqueAssembly in uniqueAssemblies.Values) { Logger.LogDebug($"Processing referenced assembly {uniqueAssembly.Name}, version={uniqueAssembly.Version}"); var assemblyEntity = GetOrAddAssemblyEntity(uniqueAssembly); var assemblyVersionEntity = GetOrAddAssemblyVersionEntity(assemblyEntity, uniqueAssembly); GetOrAddPackageAssemblyVersionEntity(packageEntity, packageVersionEntity, assemblyEntity, assemblyVersionEntity); } }
public static void TestMethodBody1() { using (MetadataLoadContext lc = new MetadataLoadContext(new CoreMetadataAssemblyResolver(), "mscorlib")) { Assembly coreAssembly = lc.LoadFromStream(TestUtils.CreateStreamForCoreAssembly()); Assembly a = lc.LoadFromByteArray(TestData.s_AssemblyWithMethodBodyImage); Type nonsense = a.GetType("Nonsense`1", throwOnError: true); Type theT = nonsense.GetTypeInfo().GenericTypeParameters[0]; MethodInfo m = nonsense.GetMethod("Foo"); Type theM = m.GetGenericArguments()[0]; MethodBody mb = m.GetMethodBody(); byte[] il = mb.GetILAsByteArray(); Assert.Equal <byte>(TestData.s_AssemblyWithMethodBodyILBytes, il); Assert.Equal(4, mb.MaxStackSize); Assert.True(mb.InitLocals); Assert.Equal(0x11000001, mb.LocalSignatureMetadataToken); IList <LocalVariableInfo> lvis = mb.LocalVariables; Assert.Equal(10, lvis.Count); Assert.Equal(0, lvis[0].LocalIndex); Assert.False(lvis[0].IsPinned); Assert.Equal(coreAssembly.GetType("System.Single", throwOnError: true), lvis[0].LocalType); Assert.Equal(1, lvis[1].LocalIndex); Assert.False(lvis[1].IsPinned); Assert.Equal(coreAssembly.GetType("System.Double", throwOnError: true), lvis[1].LocalType); Assert.Equal(2, lvis[2].LocalIndex); Assert.False(lvis[2].IsPinned); Assert.Equal(theT, lvis[2].LocalType); Assert.Equal(3, lvis[3].LocalIndex); Assert.False(lvis[3].IsPinned); Assert.Equal(theT.MakeArrayType(), lvis[3].LocalType); Assert.Equal(4, lvis[4].LocalIndex); Assert.False(lvis[4].IsPinned); Assert.Equal(coreAssembly.GetType("System.Collections.Generic.IList`1", throwOnError: true).MakeGenericType(theM), lvis[4].LocalType); Assert.Equal(5, lvis[5].LocalIndex); Assert.False(lvis[5].IsPinned); Assert.Equal(coreAssembly.GetType("System.String", throwOnError: true), lvis[5].LocalType); Assert.Equal(6, lvis[6].LocalIndex); Assert.False(lvis[6].IsPinned); Assert.Equal(coreAssembly.GetType("System.Int32", throwOnError: true).MakeArrayType(), lvis[6].LocalType); Assert.Equal(7, lvis[7].LocalIndex); Assert.True(lvis[7].IsPinned); Assert.Equal(coreAssembly.GetType("System.Int32", throwOnError: true).MakeByRefType(), lvis[7].LocalType); Assert.Equal(8, lvis[8].LocalIndex); Assert.False(lvis[8].IsPinned); Assert.Equal(coreAssembly.GetType("System.Int32", throwOnError: true).MakeArrayType(), lvis[8].LocalType); Assert.Equal(9, lvis[9].LocalIndex); Assert.False(lvis[9].IsPinned); Assert.Equal(coreAssembly.GetType("System.Boolean", throwOnError: true), lvis[9].LocalType); IList <ExceptionHandlingClause> ehcs = mb.ExceptionHandlingClauses; Assert.Equal(2, ehcs.Count); ExceptionHandlingClause ehc = ehcs[0]; Assert.Equal(ExceptionHandlingClauseOptions.Finally, ehc.Flags); Assert.Equal(97, ehc.TryOffset); Assert.Equal(41, ehc.TryLength); Assert.Equal(138, ehc.HandlerOffset); Assert.Equal(5, ehc.HandlerLength); ehc = ehcs[1]; Assert.Equal(ExceptionHandlingClauseOptions.Filter, ehc.Flags); Assert.Equal(88, ehc.TryOffset); Assert.Equal(58, ehc.TryLength); Assert.Equal(172, ehc.HandlerOffset); Assert.Equal(16, ehc.HandlerLength); Assert.Equal(146, ehc.FilterOffset); } }
public static void TestEHClauses() { using (MetadataLoadContext lc = new MetadataLoadContext(new CoreMetadataAssemblyResolver(), "mscorlib")) { Assembly coreAssembly = lc.LoadFromStream(TestUtils.CreateStreamForCoreAssembly()); Assembly a = lc.LoadFromByteArray(TestData.s_AssemblyWithEhClausesImage); Type gt = a.GetType("G`1", throwOnError: true); Type et = a.GetType("MyException`2", throwOnError: true); Type gtP0 = gt.GetGenericTypeParameters()[0]; Type etP0 = et.GetGenericTypeParameters()[0]; Type etP1 = et.GetGenericTypeParameters()[1]; { MethodInfo m = gt.GetMethod("Catch"); Type theM = m.GetGenericArguments()[0]; MethodBody body = m.GetMethodBody(); IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses; Assert.Equal(1, ehs.Count); ExceptionHandlingClause eh = ehs[0]; Assert.Equal(ExceptionHandlingClauseOptions.Clause, eh.Flags); Assert.Equal(1, eh.TryOffset); Assert.Equal(15, eh.TryLength); Assert.Equal(16, eh.HandlerOffset); Assert.Equal(16, eh.HandlerLength); Assert.Throws <InvalidOperationException>(() => eh.FilterOffset); Assert.Equal(et.MakeGenericType(gtP0, theM), eh.CatchType); } { Type sysInt32 = coreAssembly.GetType("System.Int32", throwOnError: true); Type sysSingle = coreAssembly.GetType("System.Single", throwOnError: true); MethodInfo m = gt.MakeGenericType(sysInt32).GetMethod("Catch").MakeGenericMethod(sysSingle); MethodBody body = m.GetMethodBody(); IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses; Assert.Equal(1, ehs.Count); ExceptionHandlingClause eh = ehs[0]; Assert.Equal(ExceptionHandlingClauseOptions.Clause, eh.Flags); Assert.Equal(1, eh.TryOffset); Assert.Equal(15, eh.TryLength); Assert.Equal(16, eh.HandlerOffset); Assert.Equal(16, eh.HandlerLength); Assert.Throws <InvalidOperationException>(() => eh.FilterOffset); Assert.Equal(et.MakeGenericType(sysInt32, sysSingle), eh.CatchType); } { MethodInfo m = gt.GetMethod("Finally"); MethodBody body = m.GetMethodBody(); IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses; Assert.Equal(1, ehs.Count); ExceptionHandlingClause eh = ehs[0]; Assert.Equal(ExceptionHandlingClauseOptions.Finally, eh.Flags); Assert.Equal(1, eh.TryOffset); Assert.Equal(15, eh.TryLength); Assert.Equal(16, eh.HandlerOffset); Assert.Equal(14, eh.HandlerLength); Assert.Throws <InvalidOperationException>(() => eh.FilterOffset); Assert.Throws <InvalidOperationException>(() => eh.CatchType); } { MethodInfo m = gt.GetMethod("Fault"); MethodBody body = m.GetMethodBody(); IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses; Assert.Equal(1, ehs.Count); ExceptionHandlingClause eh = ehs[0]; Assert.Equal(ExceptionHandlingClauseOptions.Fault, eh.Flags); Assert.Equal(1, eh.TryOffset); Assert.Equal(15, eh.TryLength); Assert.Equal(16, eh.HandlerOffset); Assert.Equal(14, eh.HandlerLength); Assert.Throws <InvalidOperationException>(() => eh.FilterOffset); Assert.Throws <InvalidOperationException>(() => eh.CatchType); } { MethodInfo m = gt.GetMethod("Filter"); MethodBody body = m.GetMethodBody(); IList <ExceptionHandlingClause> ehs = body.ExceptionHandlingClauses; Assert.Equal(1, ehs.Count); ExceptionHandlingClause eh = ehs[0]; Assert.Equal(ExceptionHandlingClauseOptions.Filter, eh.Flags); Assert.Equal(1, eh.TryOffset); Assert.Equal(15, eh.TryLength); Assert.Equal(40, eh.HandlerOffset); Assert.Equal(16, eh.HandlerLength); Assert.Equal(16, eh.FilterOffset); Assert.Throws <InvalidOperationException>(() => eh.CatchType); } } }