Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RequiresAssemblyFiles attribute #56196

Merged
merged 16 commits into from
Jul 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ public override string[] GetManifestResourceNames()
throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override FileStream GetFile(string name)
{
throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override FileStream[] GetFiles(bool getResourceModules)
{
throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
Expand All @@ -104,7 +106,7 @@ public override FileStream[] GetFiles(bool getResourceModules)

public override string Location => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);

[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);

[RequiresUnreferencedCode("Types might be removed")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,7 @@ internal Type[] GetTypesNoLock()
return GetType(parameters, baseType);
}

[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
public override string FullyQualifiedName => _moduleData._moduleName;

[RequiresUnreferencedCode("Trimming changes metadata tokens")]
Expand Down Expand Up @@ -785,6 +786,7 @@ public override MethodInfo[] GetMethods(BindingFlags bindingFlags)

public override string ScopeName => InternalModule.ScopeName;

[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
public override string Name => InternalModule.Name;

public override Assembly Assembly => _assemblyBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private static extern bool GetCodeBase(QCallAssembly assembly,
return null;
}

[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override string? CodeBase
{
get
Expand Down Expand Up @@ -372,6 +372,7 @@ private static extern void InternalLoad(ObjectHandleOnStack assemblyName,

// Returns the file in the File table of the manifest that matches the
// given name. (Name should not include path.)
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override FileStream? GetFile(string name)
{
if (Location.Length == 0)
Expand All @@ -389,6 +390,7 @@ private static extern void InternalLoad(ObjectHandleOnStack assemblyName,
FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false);
}

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override FileStream[] GetFiles(bool getResourceModules)
{
if (Location.Length == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
return retType;
}

[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
internal string GetFullyQualifiedName()
{
string? fullyQualifiedName = null;
Expand All @@ -458,9 +459,10 @@ internal string GetFullyQualifiedName()
return fullyQualifiedName!;
}

[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
public override string FullyQualifiedName => GetFullyQualifiedName();

[RequiresUnreferencedCode("Types might be removed")]
[RequiresUnreferencedCode("Types might be removed")]
public override Type[] GetTypes()
{
return GetTypes(this);
Expand Down Expand Up @@ -527,6 +529,7 @@ public override string ScopeName
}
}

[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
public override string Name
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.ComponentModel.Design;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;

Expand Down Expand Up @@ -40,6 +41,10 @@ protected virtual string GetKey(Type type)
/// <summary>
/// Gets a license for the instance of the component and determines if it is valid.
/// </summary>
[UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles",
Justification = "Only used for when Location is non-empty")]
[UnconditionalSuppressMessage("SingleFile", "IL3000:RequiresAssemblyFiles",
Justification = "Location is checked for empty")]
public override License? GetLicense(LicenseContext context, Type type, object? instance, bool allowExceptions)
{
LicFileLicense? lic = null;
Expand Down Expand Up @@ -69,30 +74,33 @@ protected virtual string GetKey(Type type)
}
}

if (modulePath == null)
if (type.Assembly.Location.Length != 0)
{
modulePath = type.Module.FullyQualifiedName;
}
if (modulePath == null)
{
modulePath = type.Module.FullyQualifiedName;
}

string? moduleDir = Path.GetDirectoryName(modulePath);
string licenseFile = moduleDir + "\\" + type.FullName + ".lic";
string? moduleDir = Path.GetDirectoryName(modulePath);
string licenseFile = moduleDir + "\\" + type.FullName + ".lic";

Debug.WriteLine($"Looking for license in: {licenseFile}");
if (File.Exists(licenseFile))
{
Stream licStream = new FileStream(licenseFile, FileMode.Open, FileAccess.Read, FileShare.Read);
StreamReader sr = new StreamReader(licStream);
string? s = sr.ReadLine();
sr.Close();
if (IsKeyValid(s, type))
Debug.WriteLine($"Looking for license in: {licenseFile}");
if (File.Exists(licenseFile))
{
lic = new LicFileLicense(this, GetKey(type));
Stream licStream = new FileStream(licenseFile, FileMode.Open, FileAccess.Read, FileShare.Read);
StreamReader sr = new StreamReader(licStream);
string? s = sr.ReadLine();
sr.Close();
if (IsKeyValid(s, type))
{
lic = new LicFileLicense(this, GetKey(type));
}
}
}

if (lic != null)
{
context!.SetSavedLicenseKey(type, lic.LicenseKey);
if (lic != null)
{
context!.SetSavedLicenseKey(type, lic.LicenseKey);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ internal sealed class ClientConfigPaths

[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "Code handles single file case")]
[UnconditionalSuppressMessage("SingleFile", "IL3002: RequiresAssemblyFiles on Module.Name",
Justification = "Code handles single file case")]
private ClientConfigPaths(string exePath, bool includeUserConfig)
{
_includesUserConfig = includeUserConfig;
Expand Down Expand Up @@ -222,6 +224,8 @@ private static string CombineIfValid(string path1, string path2)
// The evidence we use, in priority order, is Strong Name, Url and Exe Path. If one of
// these is found, we compute a SHA1 hash of it and return a suffix based on that.
// If none is found, we return null.
[UnconditionalSuppressMessage("SingleFile", "IL3002: RequiresAssemblyFiles on Module.Name",
Justification = "Code handles single file case")]
private static string GetTypeAndHashSuffix(string exePath, bool isSingleFile)
{
Assembly assembly = Assembly.GetEntryAssembly();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ public virtual IEnumerable<Type> ExportedTypes
[RequiresUnreferencedCode("Types might be removed")]
public virtual Type[] GetForwardedTypes() { throw NotImplemented.ByDesign; }

[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
internal const string ThrowingMessageInRAF = "This member throws an exception for assemblies embedded in a single-file app";

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public virtual string? CodeBase => throw NotImplemented.ByDesign;
public virtual MethodInfo? EntryPoint => throw NotImplemented.ByDesign;
public virtual string? FullName => throw NotImplemented.ByDesign;
Expand Down Expand Up @@ -116,7 +118,7 @@ public virtual IEnumerable<Type> ExportedTypes
public virtual object[] GetCustomAttributes(bool inherit) { throw NotImplemented.ByDesign; }
public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }

[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public virtual string EscapedCodeBase => AssemblyName.EscapeCodeBase(CodeBase);

[RequiresUnreferencedCode("Assembly.CreateInstance is not supported with trimming. Use Type.GetType instead.")]
Expand Down Expand Up @@ -153,9 +155,11 @@ public virtual IEnumerable<Type> ExportedTypes
public virtual Assembly GetSatelliteAssembly(CultureInfo culture) { throw NotImplemented.ByDesign; }
public virtual Assembly GetSatelliteAssembly(CultureInfo culture, Version? version) { throw NotImplemented.ByDesign; }

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public virtual FileStream? GetFile(string name) { throw NotImplemented.ByDesign; }
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public virtual FileStream[] GetFiles() => GetFiles(getResourceModules: false);
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public virtual FileStream[] GetFiles(bool getResourceModules) { throw NotImplemented.ByDesign; }

public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw NotImplemented.ByDesign; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace System.Reflection.Emit
{
public sealed partial class AssemblyBuilder : Assembly
{
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
public override string Location => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
public override MethodInfo? EntryPoint => null;
Expand All @@ -18,9 +18,11 @@ public sealed partial class AssemblyBuilder : Assembly
public override Type[] GetExportedTypes() =>
throw new NotSupportedException(SR.NotSupported_DynamicAssembly);

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override FileStream GetFile(string name) =>
throw new NotSupportedException(SR.NotSupported_DynamicAssembly);

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override FileStream[] GetFiles(bool getResourceModules) =>
throw new NotSupportedException(SR.NotSupported_DynamicAssembly);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ public abstract partial class Module : ICustomAttributeProvider, ISerializable
protected Module() { }

public virtual Assembly Assembly => throw NotImplemented.ByDesign;

internal const string UnknownStringMessageInRAF = "Returns <Unknown> for modules with no file path";
[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
public virtual string FullyQualifiedName => throw NotImplemented.ByDesign;
[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
public virtual string Name => throw NotImplemented.ByDesign;

public virtual int MDStreamVersion => throw NotImplemented.ByDesign;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

namespace System.Reflection.Context.Delegation
{
Expand All @@ -22,6 +23,11 @@ public override Assembly Assembly
get { return UnderlyingModule.Assembly; }
}

internal const string UnknownStringMessageInRAF = "Returns <Unknown> for modules with no file path";

#if NET5_0_OR_GREATER
[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
#endif
public override string FullyQualifiedName
{
get { return UnderlyingModule.FullyQualifiedName; }
Expand All @@ -42,6 +48,9 @@ public override Guid ModuleVersionId
get { return UnderlyingModule.ModuleVersionId; }
}

#if NET5_0_OR_GREATER
[RequiresAssemblyFiles(UnknownStringMessageInRAF)]
#endif
public override string Name
{
get { return UnderlyingModule.Name; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ internal AssemblyBuilder() { }
public System.Reflection.Emit.ModuleBuilder? GetDynamicModule(string name) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public override System.Type[] GetExportedTypes() { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
public override System.IO.FileStream GetFile(string name) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("This member throws an exception for assemblies embedded in a single-file app")]
public override System.IO.FileStream[] GetFiles(bool getResourceModules) { throw null; }
public override int GetHashCode() { throw null; }
public override System.Reflection.Module[] GetLoadedModules(bool getResourceModules) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection.Metadata;

Expand Down Expand Up @@ -51,6 +52,8 @@ public sealed override string[] GetManifestResourceNames()
return resourceNames;
}

[UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles on Module.GetFile",
Justification = "ResourceLocation should never be ContainedInAnotherAssembly if embedded in a single-file")]
public sealed override Stream? GetManifestResourceStream(string name)
{
if (name == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;

namespace System.Reflection.TypeLoading
Expand All @@ -16,6 +17,9 @@ internal abstract partial class RoAssembly
public sealed override Module? GetModule(string name) => GetRoModule(name);
public sealed override Module[] GetModules(bool getResourceModules) => ComputeRoModules(getResourceModules).CloneArray<Module>();

#if NET5_0_OR_GREATER
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
#endif
public sealed override FileStream? GetFile(string name)
{
Module? m = GetModule(name);
Expand All @@ -24,6 +28,9 @@ internal abstract partial class RoAssembly
return new FileStream(m.FullyQualifiedName, FileMode.Open, FileAccess.Read, FileShare.Read);
}

#if NET5_0_OR_GREATER
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
#endif
public sealed override FileStream[] GetFiles(bool getResourceModules)
{
Module[] m = GetModules(getResourceModules);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,18 @@ protected RoAssembly(MetadataLoadContext loader, int assemblyFileCount)
public sealed override string FullName => _lazyFullName ?? (_lazyFullName = GetName().FullName);
private volatile string? _lazyFullName;

internal const string ThrowingMessageInRAF = "This member throws an exception for assemblies embedded in a single-file app";

// Location and codebase
public abstract override string Location { get; }
#if NET5_0_OR_GREATER
[Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
#endif
public sealed override string CodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase);
#if NET5_0_OR_GREATER
[Obsolete(Obsoletions.CodeBaseMessage, DiagnosticId = Obsoletions.CodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")]
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
#endif
public sealed override string EscapedCodeBase => throw new NotSupportedException(SR.NotSupported_AssemblyCodeBase);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;
using System.Reflection.Metadata;

namespace System.Reflection.TypeLoading.Ecma
Expand All @@ -16,6 +17,8 @@ internal sealed partial class EcmaModule
/// If a type is not contained or forwarded from the assembly, this method returns null (does not throw.)
/// This supports the "throwOnError: false" behavior of Module.GetType(string, bool).
/// </summary>
[UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles on FullyQualifiedName",
Justification = "FullyQualifiedName is only used for exception message")]
protected sealed override RoDefinitionType? GetTypeCoreNoCache(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name, out Exception? e)
{
MetadataReader reader = Reader;
Expand Down
Loading