1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-10 01:50:53 +09:00

Enable single file analyzer in the runtime (#50894)

Summary:
Enables single file analyzer in the runtime by adding the ILLink.Analyzers package and the property EnableSingleFileAnalyzer equals to true
Deletes entries IL3000 and IL3001 in the CodeAnalysis.ruleset so the analyzer can actually produce these warnings otherwise the analyzer execution would be skipped. *Note*: tests warnings are controlled by CodeAnalysis.test.ruleset (this PR adds IL3002 to the CodeAnalysis.test.ruleset to disable the warning on tests)
Resolve warnings on single file dangerous patterns by:
- Annotating incompatible single file patterns with RequiresAssemblyFiles
- Suppressing the warning (because there is code that handles the incompatible code)
- Fixing the issue on code (remove the incompatible code and replace it with something that won't fail)
- Opening an issue to track fix and either annotate/suppress the current behavior
This commit is contained in:
Tlakaelel Axayakatl Ceja 2021-05-19 13:04:03 -07:00 committed by GitHub
parent a287b6d54d
commit aad916c711
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 129 additions and 20 deletions

View file

@ -3,11 +3,13 @@
<CodeAnalysisRuleset>$(MSBuildThisFileDirectory)CodeAnalysis.ruleset</CodeAnalysisRuleset>
<!-- Disable analyzers in sourcebuild -->
<RunAnalyzers Condition="'$(DotNetBuildFromSource)' == 'true'">false</RunAnalyzers>
<EnableSingleFileAnalyzer>true</EnableSingleFileAnalyzer>
</PropertyGroup>
<ItemGroup Condition="'$(RunAnalyzers)' != 'false'">
<PackageReference Include="Microsoft.DotNet.CodeAnalysis" Version="$(MicrosoftDotNetCodeAnalysisVersion)" PrivateAssets="all" IsImplicitlyDefined="true" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="$(MicrosoftCodeAnalysisNetAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="$(MicrosoftCodeAnalysisCSharpCodeStyleVersion)" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.NET.ILLink.Analyzers" Version="$(MicrosoftNETILLinkAnalyzerPackageVersion)" PrivateAssets="all" />
</ItemGroup>
</Project>

View file

@ -254,8 +254,6 @@
<Rule Id="CA5401" Action="None" /> <!-- Do not use CreateEncryptor with non-default IV -->
<Rule Id="CA5402" Action="None" /> <!-- Use CreateEncryptor with the default IV -->
<Rule Id="CA5403" Action="None" /> <!-- Do not hard-code certificate -->
<Rule Id="IL3000" Action="None" /> <!-- Avoid using accessing Assembly file path when publishing as a single-file -->
<Rule Id="IL3001" Action="None" /> <!-- Avoid using accessing Assembly file path when publishing as a single-file -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<Rule Id="AD0001" Action="None" /> <!-- Analyzer threw an exception -->

View file

@ -255,6 +255,7 @@
<Rule Id="CA5403" Action="None" /> <!-- Do not hard-code certificate -->
<Rule Id="IL3000" Action="None" /> <!-- Avoid using accessing Assembly file path when publishing as a single-file -->
<Rule Id="IL3001" Action="None" /> <!-- Avoid using accessing Assembly file path when publishing as a single-file -->
<Rule Id="IL3002" Action="None" /> <!-- Using member with RequiresAssemblyFilesAttribute can break functionality when embedded in a single-file app -->
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<Rule Id="AD0001" Action="None" /> <!-- Analyzer threw an exception -->

View file

@ -162,6 +162,7 @@
<MicrosoftPrivateIntellisenseVersion>5.0.0-preview-20201009.2</MicrosoftPrivateIntellisenseVersion>
<!-- ILLink -->
<MicrosoftNETILLinkTasksVersion>6.0.100-preview.5.21267.3</MicrosoftNETILLinkTasksVersion>
<MicrosoftNETILLinkAnalyzerPackageVersion>$(MicrosoftNETILLinkTasksVersion)</MicrosoftNETILLinkAnalyzerPackageVersion>
<!-- ICU -->
<MicrosoftNETCoreRuntimeICUTransportVersion>6.0.0-preview.5.21267.1</MicrosoftNETCoreRuntimeICUTransportVersion>
<!-- Mono LLVM -->

View file

@ -62,10 +62,12 @@ namespace Microsoft.Extensions.DependencyModel
public DependencyContext(Microsoft.Extensions.DependencyModel.TargetInfo target, Microsoft.Extensions.DependencyModel.CompilationOptions compilationOptions, System.Collections.Generic.IEnumerable<Microsoft.Extensions.DependencyModel.CompilationLibrary> compileLibraries, System.Collections.Generic.IEnumerable<Microsoft.Extensions.DependencyModel.RuntimeLibrary> runtimeLibraries, System.Collections.Generic.IEnumerable<Microsoft.Extensions.DependencyModel.RuntimeFallbacks> runtimeGraph) { }
public Microsoft.Extensions.DependencyModel.CompilationOptions CompilationOptions { get { throw null; } }
public System.Collections.Generic.IReadOnlyList<Microsoft.Extensions.DependencyModel.CompilationLibrary> CompileLibraries { get { throw null; } }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static Microsoft.Extensions.DependencyModel.DependencyContext Default { get { throw null; } }
public System.Collections.Generic.IReadOnlyList<Microsoft.Extensions.DependencyModel.RuntimeFallbacks> RuntimeGraph { get { throw null; } }
public System.Collections.Generic.IReadOnlyList<Microsoft.Extensions.DependencyModel.RuntimeLibrary> RuntimeLibraries { get { throw null; } }
public Microsoft.Extensions.DependencyModel.TargetInfo Target { get { throw null; } }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static Microsoft.Extensions.DependencyModel.DependencyContext Load(System.Reflection.Assembly assembly) { throw null; }
public Microsoft.Extensions.DependencyModel.DependencyContext Merge(Microsoft.Extensions.DependencyModel.DependencyContext other) { throw null; }
}
@ -95,6 +97,7 @@ namespace Microsoft.Extensions.DependencyModel
{
public DependencyContextLoader() { }
public static Microsoft.Extensions.DependencyModel.DependencyContextLoader Default { get { throw null; } }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public Microsoft.Extensions.DependencyModel.DependencyContext Load(System.Reflection.Assembly assembly) { throw null; }
}
public partial class DependencyContextWriter

View file

@ -4,5 +4,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Microsoft.Extensions.DependencyModel.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\RequiresAssemblyFilesAttribute.cs" />
</ItemGroup>
</Project>

View file

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
@ -10,6 +11,9 @@ namespace Microsoft.Extensions.DependencyModel
{
public class DependencyContext
{
[UnconditionalSuppressMessage("SingleFile", "IL3002:Avoid calling members marked with 'RequiresAssemblyFilesAttribute' when publishing as a single-file",
Justification = "The annotation should be on the static constructor but is Compiler Generated, annotating the caller Default method instead")]
private static readonly Lazy<DependencyContext> _defaultContext = new Lazy<DependencyContext>(LoadDefault);
public DependencyContext(TargetInfo target,
@ -46,6 +50,7 @@ namespace Microsoft.Extensions.DependencyModel
RuntimeGraph = runtimeGraph.ToArray();
}
[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static DependencyContext Default => _defaultContext.Value;
public TargetInfo Target { get; }
@ -74,6 +79,7 @@ namespace Microsoft.Extensions.DependencyModel
);
}
[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
private static DependencyContext LoadDefault()
{
var entryAssembly = Assembly.GetEntryAssembly();
@ -85,6 +91,7 @@ namespace Microsoft.Extensions.DependencyModel
return Load(entryAssembly);
}
[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public static DependencyContext Load(Assembly assembly)
{
return DependencyContextLoader.Default.Load(assembly);

View file

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
@ -50,6 +51,7 @@ namespace Microsoft.Extensions.DependencyModel
return assembly.GetManifestResourceStream(name);
}
[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
public DependencyContext Load(Assembly assembly)
{
if (assembly == null)
@ -103,6 +105,7 @@ namespace Microsoft.Extensions.DependencyModel
return null;
}
[RequiresAssemblyFiles(Message = "DependencyContext for an assembly from a application published as single-file is not supported. The method will return null. Make sure the calling code can handle this case.")]
private DependencyContext LoadAssemblyContext(Assembly assembly, IDependencyContextReader reader)
{
using (Stream stream = GetResourceStream(assembly, assembly.GetName().Name + DepsJsonExtension))
@ -125,6 +128,7 @@ namespace Microsoft.Extensions.DependencyModel
return null;
}
[RequiresAssemblyFiles(Message = "The use of DependencyContextLoader is not supported when publishing as single-file")]
private string GetDepsJsonPath(Assembly assembly)
{
// Assemblies loaded in memory (e.g. single file) return empty string from Location.

View file

@ -11,6 +11,8 @@ Microsoft.Extensions.DependencyModel.DependencyContext</PackageDescription>
<ItemGroup>
<Compile Include="$(CoreLibSharedDir)\System\Numerics\Hashing\HashHelpers.cs"
Link="System\Numerics\Hashing\HashHelpers.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\RequiresAssemblyFilesAttribute.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>
<ItemGroup>
@ -29,4 +31,5 @@ Microsoft.Extensions.DependencyModel.DependencyContext</PackageDescription>
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Encodings.Web\src\System.Text.Encodings.Web.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
</ItemGroup>
</Project>

View file

@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
@ -27,6 +28,8 @@ namespace Microsoft.NETCore.Platforms.BuildTasks
// has run.
}
[UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file",
Justification = "The code has a fallback to use AppDomain.CurrentDomain.BaseDirectory so it will work correctly in single-file")]
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
// apply any existing policy

View file

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.SDK">
<Project Sdk="Microsoft.NET.SDK">
<!-- These are wrapper project files for packaging.-->
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppToolCurrent);net472</TargetFrameworks>
@ -21,6 +21,7 @@
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<Compile Include="BuildTask.Desktop.cs" />
<Compile Include="AssemblyResolver.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>
<ItemGroup>

View file

@ -6,9 +6,13 @@
<StringResourcesName>FxResources.$(AssemblyName.Replace('-', '_')).SR</StringResourcesName>
<OutputType>Exe</OutputType>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<EnableSingleFileAnalyzer>false</EnableSingleFileAnalyzer>
</PropertyGroup>
<ItemGroup>
<Compile Include="Sgen.cs" />
</ItemGroup>
<Import Project=".\GenerateThisAssemblyCs.targets" />
</Project>

View file

@ -182,6 +182,9 @@
<Compile Include="$(CommonPath)System\Composition\Diagnostics\TraceWriter.cs"
Link="Common\System\Composition\Diagnostics\TraceWriter.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard2.0'">
<Reference Include="Microsoft.Win32.Primitives" />
<Reference Include="System.Collections" />

View file

@ -543,6 +543,8 @@ namespace System.ComponentModel.Composition.Hosting
private string GetDisplayName() =>
$"{GetType().Name} (Assembly=\"{Assembly.FullName}\")"; // NOLOC
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "Setting a CodeBase is single file compatible")]
private static Assembly LoadAssembly(string codeBase)
{
Requires.NotNullOrEmpty(codeBase, nameof(codeBase));

View file

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Collections;
@ -57,6 +58,8 @@ namespace System.ComponentModel.Design
return uri.LocalPath + uri.Fragment;
}
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "Suppressing the warning until gets fixed, see https://github.com/dotnet/runtime/issues/50821")]
public override string GetSavedLicenseKey(Type type, Assembly resourceAssembly)
{
if (_savedLicenseKeys == null || _savedLicenseKeys[type.AssemblyQualifiedName] == null)

View file

@ -251,6 +251,7 @@
<Compile Include="$(CommonPath)System\IO\TempFileCollection.cs"
Link="Common\System\IO\TempFileCollection.cs" />
<Compile Include="$(CommonPath)System\Obsoletions.cs" Link="Common\System\Obsoletions.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
<ProjectReference Include="$(LibrariesProjectRoot)System.Security.Cryptography.ProtectedData\src\System.Security.Cryptography.ProtectedData.csproj" />

View file

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Reflection;
@ -28,6 +29,8 @@ namespace System.Configuration
private readonly bool _includesUserConfig;
private string _companyName;
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "Code handles single file case")]
private ClientConfigPaths(string exePath, bool includeUserConfig)
{
_includesUserConfig = includeUserConfig;

View file

@ -128,7 +128,9 @@
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Win32.Registry\src\Microsoft.Win32.Registry.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Threading.AccessControl\src\System.Threading.AccessControl.csproj" />
</ItemGroup>
<ItemGroup Condition="!$(TargetFramework.StartsWith('$(NetCoreAppCurrent)'))">
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>
<!-- Ensure we run ResolveProjectReferences to add the message DLL to the package.
We do this here rather than in the pkgproj to ensure the package paths are in sync -->
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">

View file

@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
@ -691,6 +692,8 @@ namespace System.Diagnostics
return null;
}
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "The code handles if the path is null by calling AppContext.BaseDirectory")]
internal static string GetDllPath(string machineName)
{
string dllPath = Path.Combine(NetFrameworkUtils.GetLatestBuildDllDirectory(machineName), DllName);

View file

@ -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;
using System.Security;
using System.Threading;
@ -27,6 +28,8 @@ namespace System.IO.IsolatedStorage
return dataDirectory;
}
[UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file",
Justification = "Code handles single-file deployment by using the information of the .exe file")]
internal static void GetDefaultIdentityAndHash(out object identity, out string hash, char separator)
{
// In .NET Framework IsolatedStorage uses identity from System.Security.Policy.Evidence to build
@ -53,9 +56,6 @@ namespace System.IO.IsolatedStorage
throw new IsolatedStorageException(SR.IsolatedStorage_Init);
AssemblyName assemblyName = assembly.GetName();
#pragma warning disable SYSLIB0012
Uri codeBase = new Uri(assembly.CodeBase!);
#pragma warning restore SYSLIB0012
hash = IdentityHelper.GetNormalizedStrongNameHash(assemblyName)!;
if (hash != null)
@ -65,8 +65,15 @@ namespace System.IO.IsolatedStorage
}
else
{
hash = "Url" + separator + IdentityHelper.GetNormalizedUriHash(codeBase);
identity = codeBase;
string? location = assembly.Location;
// In case of SingleFile deployment, Assembly.Location is empty.
if (location == string.Empty)
location = Environment.ProcessPath;
if (string.IsNullOrEmpty(location))
throw new IsolatedStorageException(SR.IsolatedStorage_Init);
Uri locationUri = new Uri(location);
hash = "Url" + separator + IdentityHelper.GetNormalizedUriHash(locationUri);
identity = locationUri;
}
}

View file

@ -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;
@ -8,6 +9,8 @@ namespace System
{
public static partial class AppContext
{
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "Single File apps should always set APP_CONTEXT_BASE_DIRECTORY therefore code handles Assembly.Location equals null")]
private static string GetBaseDirectoryCore()
{
// Fallback path for hosts that do not set APP_CONTEXT_BASE_DIRECTORY explicitly

View file

@ -12,7 +12,12 @@ namespace System.Diagnostics.CodeAnalysis
AttributeTargets.Property,
Inherited = false,
AllowMultiple = false)]
public sealed class RequiresAssemblyFilesAttribute : Attribute
#if SYSTEM_PRIVATE_CORELIB
public
#else
internal
#endif
sealed class RequiresAssemblyFilesAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="RequiresAssemblyFilesAttribute"/> class.

View file

@ -81,6 +81,7 @@ namespace System.Reflection
[RequiresUnreferencedCode("Types might be removed")]
public virtual Type[] GetForwardedTypes() { throw NotImplemented.ByDesign; }
[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
public virtual string? CodeBase => throw NotImplemented.ByDesign;
public virtual MethodInfo? EntryPoint => throw NotImplemented.ByDesign;
public virtual string? FullName => throw NotImplemented.ByDesign;
@ -115,6 +116,7 @@ namespace System.Reflection
public virtual object[] GetCustomAttributes(bool inherit) { throw NotImplemented.ByDesign; }
public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
public virtual string EscapedCodeBase => AssemblyName.EscapeCodeBase(CodeBase);
[RequiresUnreferencedCode("Assembly.CreateInstance is not supported with trimming. Use Type.GetType instead.")]
@ -152,6 +154,7 @@ namespace System.Reflection
public virtual Assembly GetSatelliteAssembly(CultureInfo culture, Version? version) { throw NotImplemented.ByDesign; }
public virtual FileStream? GetFile(string name) { throw NotImplemented.ByDesign; }
[RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
public virtual FileStream[] GetFiles() => GetFiles(getResourceModules: false);
public virtual FileStream[] GetFiles(bool getResourceModules) { throw NotImplemented.ByDesign; }
@ -268,6 +271,8 @@ namespace System.Reflection
}
[RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed")]
[UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file",
Justification = "The assembly is loaded by specifying a path outside of the single-file bundle, the location of the path will not be empty if the path exist, otherwise it will be handled as null")]
private static Assembly? LoadFromResolveHandler(object? sender, ResolveEventArgs args)
{
Assembly? requestingAssembly = args.RequestingAssembly;

View file

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Configuration.Assemblies;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using System.Text;
using CultureInfo = System.Globalization.CultureInfo;
@ -59,10 +60,12 @@ namespace System.Reflection
public string? CodeBase
{
[RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
get => _codeBase;
set => _codeBase = value;
}
[RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
public string? EscapedCodeBase
{
get
@ -258,6 +261,7 @@ namespace System.Reflection
return refName.Equals(defName, StringComparison.OrdinalIgnoreCase);
}
[RequiresAssemblyFiles(Message = "The code will return an empty string for assemblies embedded in a single-file app")]
internal static string EscapeCodeBase(string? codebase)
{
if (codebase == null)

View file

@ -609,6 +609,8 @@ namespace System.Runtime.Loader
return context.ResolveUsingLoad(assemblyName);
}
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "The code handles the Assembly.Location equals null")]
private Assembly? GetFirstResolvedAssemblyFromResolvingEvent(AssemblyName assemblyName)
{
Assembly? resolvedAssembly = null;
@ -721,6 +723,8 @@ namespace System.Runtime.Loader
return InvokeResolveEvent(AssemblyResolve, assembly, assemblyFullName);
}
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "The code handles the Assembly.Location equals null")]
private static RuntimeAssembly? InvokeResolveEvent(ResolveEventHandler? eventHandler, RuntimeAssembly assembly, string name)
{
if (eventHandler == null)
@ -752,6 +756,8 @@ namespace System.Runtime.Loader
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "Satellite assemblies have no code in them and loading is not a problem")]
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "This call is fine because native call runs before this and checks BindSatelliteResourceFromBundle")]
private Assembly? ResolveSatelliteAssembly(AssemblyName assemblyName)
{
// Called by native runtime when CultureName is not empty

View file

@ -140,6 +140,9 @@ namespace System.Xml.Serialization
// SxS: This method does not take any resource name and does not expose any resources to the caller.
// It's OK to suppress the SxS warning.
[RequiresUnreferencedCode("calls LoadFile")]
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "Annotating this as dangerous will make the core of the serializer to be marked as not safe, instead " +
"this pattern is only dangerous if using sgen only. See https://github.com/dotnet/runtime/issues/50820")]
internal static Assembly? LoadGeneratedAssembly(Type type, string? defaultNamespace, out XmlSerializerImplementation? contract)
{
Assembly? serializer = null;

View file

@ -629,6 +629,8 @@ namespace System.Xml.Serialization
}
[RequiresUnreferencedCode("calls GenerateSerializerToStream")]
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "Code is used on diagnostics so we fallback to print assembly.FullName if assembly.Location is empty")]
internal static bool GenerateSerializer(Type[]? types, XmlMapping[] mappings, Stream stream)
{
if (types == null || types.Length == 0)
@ -660,7 +662,10 @@ namespace System.Xml.Serialization
}
else if (type.Assembly != assembly)
{
throw new ArgumentException(SR.Format(SR.XmlPregenOrphanType, type.FullName, assembly.Location), nameof(types));
string? nameOrLocation = assembly.Location;
if (nameOrLocation == string.Empty)
nameOrLocation = assembly.FullName;
throw new ArgumentException(SR.Format(SR.XmlPregenOrphanType, type.FullName, nameOrLocation), nameof(types));
}
}

View file

@ -63,5 +63,6 @@
<Compile Include="System\Reflection\Context\Virtual\VirtualPropertyInfo.PropertyGetter.cs" />
<Compile Include="System\Reflection\Context\Virtual\VirtualPropertyInfo.PropertySetter.cs" />
<Compile Include="System\Reflection\Context\Virtual\VirtualReturnParameter.cs" />
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\RequiresAssemblyFilesAttribute.cs" />
</ItemGroup>
</Project>

View file

@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Security;
@ -21,6 +22,7 @@ namespace System.Reflection.Context.Delegation
UnderlyingAssembly = assembly;
}
[RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3000")]
public override string Location
{
get { return UnderlyingAssembly.Location; }
@ -98,16 +100,19 @@ namespace System.Reflection.Context.Delegation
return UnderlyingAssembly.GetExportedTypes();
}
[RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFile(string)' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream GetFile(string name)
{
return UnderlyingAssembly.GetFile(name);
}
[RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFiles()' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream[] GetFiles()
{
return UnderlyingAssembly.GetFiles();
}
[RequiresAssemblyFiles(Message = "Calling 'System.Reflection.Assembly.GetFiles(bool)' will throw for assemblies embedded in a single-file app", Url = "https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/il3001")]
public override FileStream[] GetFiles(bool getResourceModules)
{
return UnderlyingAssembly.GetFiles(getResourceModules);

View file

@ -155,11 +155,17 @@
<Reference Include="System.Runtime.InteropServices" />
<Reference Include="System.Threading" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<Reference Include="System.Diagnostics.Tools" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('netstandard')) or
$(TargetFramework.StartsWith('net4'))">
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.CompilerServices.Unsafe\src\System.Runtime.CompilerServices.Unsafe.ilproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
</ItemGroup>
<!-- Application tfms (.NETCoreApp, .NETFramework) need to use the same or higher version of .NETStandard's dependencies. -->
<Choose>

View file

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
@ -32,6 +33,8 @@ namespace System.Reflection.TypeLoading.Ecma
throw new FileNotFoundException(SR.Format(SR.FileNotFoundModule, moduleName));
}
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "The code has a fallback using a ModuleResolveEventHandler")]
private FileStream? FindModuleNextToAssembly(string moduleName)
{
Assembly containingAssembly = this;

View file

@ -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;
@ -13,6 +14,8 @@ namespace System.Runtime.InteropServices
public static bool FromGlobalAccessCache(Assembly a) => false;
[UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file",
Justification = "This call is fine because the code handles the Assembly.Location equals null by calling AppDomain.CurrentDomain.BaseDirectory")]
public static string GetRuntimeDirectory()
{
string? runtimeDirectory = typeof(object).Assembly.Location;

View file

@ -7886,11 +7886,13 @@ namespace System.Reflection
{
protected Assembly() { }
[System.ObsoleteAttribute("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message="The code will throw for assemblies embedded in a single-file app")]
public virtual string? CodeBase { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> CustomAttributes { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> DefinedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } }
public virtual System.Reflection.MethodInfo? EntryPoint { get { throw null; } }
[System.ObsoleteAttribute("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message="The code will throw for assemblies embedded in a single-file app")]
public virtual string EscapedCodeBase { get { throw null; } }
public virtual System.Collections.Generic.IEnumerable<System.Type> ExportedTypes { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] get { throw null; } }
public virtual string? FullName { get { throw null; } }
@ -7925,6 +7927,7 @@ namespace System.Reflection
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
public virtual System.Type[] GetExportedTypes() { throw null; }
public virtual System.IO.FileStream? GetFile(string name) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFiles(Message = "The code will throw for assemblies embedded in a single-file app")]
public virtual System.IO.FileStream[] GetFiles() { throw null; }
public virtual System.IO.FileStream[] GetFiles(bool getResourceModules) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")]
@ -8093,10 +8096,11 @@ namespace System.Reflection
{
public AssemblyName() { }
public AssemblyName(string assemblyName) { }
public string? CodeBase { get { throw null; } set { } }
public string? CodeBase { [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message = "The code will return an empty string for assemblies embedded in a single-file app")] get { throw null; } set { } }
public System.Reflection.AssemblyContentType ContentType { get { throw null; } set { } }
public System.Globalization.CultureInfo? CultureInfo { get { throw null; } set { } }
public string? CultureName { get { throw null; } set { } }
[System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute(Message="The code will return an empty string for assemblies embedded in a single-file app")]
public string? EscapedCodeBase { get { throw null; } }
public System.Reflection.AssemblyNameFlags Flags { get { throw null; } set { } }
public string FullName { get { throw null; } }

View file

@ -342,6 +342,7 @@
<!-- Run only a small randomly chosen set of passing test suites -->
<ProjectExclusions Include="$(MSBuildThisFileDirectory)*\tests\**\*.Tests.csproj" />
<ProjectExclusions Remove="$(MSBuildThisFileDirectory)System.Collections\tests\System.Collections.Tests.csproj" />
<ProjectExclusions Remove="$(MSBuildThisFileDirectory)System.IO.IsolatedStorage\tests\System.IO.IsolatedStorage.Tests.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
@ -210,6 +211,8 @@ namespace Microsoft.WebAssembly.Diagnostics
return values;
}
[UnconditionalSuppressMessage("SingleFile", "IL3000:Avoid accessing Assembly file path when publishing as a single file",
Justification = "Suppressing the warning until gets fixed, see https://github.com/dotnet/runtime/issues/51202")]
internal static async Task<JObject> CompileAndRunTheExpression(string expression, MemberReferenceResolver resolver, CancellationToken token)
{
expression = expression.Trim();

View file

@ -3,9 +3,9 @@
<TargetFrameworks>$(NetCoreAppToolCurrent);$(TargetFrameworkForNETFramework)</TargetFrameworks>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn),CA1050</NoWarn>
<!-- Ignore nullable warnings on net4* -->
<NoWarn Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">$(NoWarn),CS8604,CS8602</NoWarn>
<EnableSingleFileAnalyzer>false</EnableSingleFileAnalyzer>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">