From 5f43e51d136df495e8f937b4f2ad01701265b019 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 9 Jun 2020 05:28:21 -0400 Subject: [PATCH] Use [MemberNotNull] to reduce use of `= null!;` (#37490) * Exclude MemberNotNull from various tools * Use [MemberNotNull] to reduce use of `= null!;` --- eng/ApiCompatExcludeAttributes.txt | 1 + eng/DefaultGenApiDocIds.txt | 1 + .../DebugCriticalHandleMinusOneIsInvalid.cs | 10 +- ...ugCriticalHandleZeroOrMinusOneIsInvalid.cs | 10 +- .../Net/DebugSafeHandleMinusOneIsInvalid.cs | 10 +- .../src/System/Net/NTAuthentication.Common.cs | 3 +- .../Concurrent/BlockingCollection.cs | 12 +- .../Specialized/NameObjectCollectionBase.cs | 9 +- .../Composition/Hosting/AssemblyCatalog.cs | 3 +- .../Composition/Hosting/DirectoryCatalog.cs | 24 ++-- .../Composition/ReflectionModel/ImportType.cs | 3 +- .../src/System/Diagnostics/Activity.cs | 3 +- .../SafeHandles/SafeProcessHandle.Unix.cs | 4 +- .../Diagnostics/PerformanceCounterLib.cs | 10 +- .../src/System/Diagnostics/SourceFilter.cs | 4 +- .../src/System/Diagnostics/SwitchAttribute.cs | 10 +- .../Diagnostics/SwitchLevelAttribute.cs | 5 +- .../ref/System.Drawing.Common.cs | 2 +- .../src/System/Drawing/Font.cs | 4 +- .../Compression/DeflateZLib/DeflateStream.cs | 4 +- .../IO/Compression/DeflateZLib/Inflater.cs | 6 +- .../System/IO/Compression/ZipArchiveEntry.cs | 6 +- .../IO/IsolatedStorage/IsolatedStorageFile.cs | 70 +++++------ .../src/System/Net/Http/HttpRequestMessage.cs | 6 +- .../src/System/Net/Http/StreamContent.cs | 4 +- .../src/System/Net/Mail/SmtpClient.cs | 9 +- .../src/System/Net/Mime/ContentDisposition.cs | 4 +- .../src/System/Net/Mime/ContentType.cs | 113 ++++++++---------- .../src/System/Net/NetworkCredential.cs | 3 +- .../Sockets/SocketAsyncEventArgs.Windows.cs | 4 +- .../src/System/Resources/ResourceReader.cs | 9 +- .../src/System/Security/AccessControl/ACE.cs | 4 +- .../src/System/Security/AccessControl/ACL.cs | 4 +- .../AccessControl/SecurityDescriptor.cs | 8 +- .../Internal/Cryptography/AppleCCCryptor.cs | 4 +- .../src/Internal/Cryptography/HMACCommon.cs | 34 +++--- .../Internal/Cryptography/OpenSslCipher.cs | 4 +- .../Security/Cryptography/AesCcm.Unix.cs | 4 +- .../Security/Cryptography/AesCcm.Windows.cs | 4 +- .../Security/Cryptography/AesGcm.Unix.cs | 4 +- .../Security/Cryptography/AesGcm.Windows.cs | 4 +- .../Cryptography/Rfc2898DeriveBytes.cs | 6 +- .../src/System/Security/Principal/SID.cs | 11 +- .../RegexCompilationInfo.cs | 12 +- 44 files changed, 255 insertions(+), 214 deletions(-) diff --git a/eng/ApiCompatExcludeAttributes.txt b/eng/ApiCompatExcludeAttributes.txt index 27c8942c9f39c..16db9ad94cda5 100644 --- a/eng/ApiCompatExcludeAttributes.txt +++ b/eng/ApiCompatExcludeAttributes.txt @@ -1 +1,2 @@ T:System.CLSCompliantAttribute +T:System.Diagnostics.CodeAnalysis.MemberNotNullAttribute diff --git a/eng/DefaultGenApiDocIds.txt b/eng/DefaultGenApiDocIds.txt index d42e3fe429762..3d6c059f110f0 100644 --- a/eng/DefaultGenApiDocIds.txt +++ b/eng/DefaultGenApiDocIds.txt @@ -8,6 +8,7 @@ T:System.ComponentModel.ToolboxItemAttribute T:System.ComponentModel.TypeDescriptionProviderAttribute T:System.Configuration.ConfigurationPropertyAttribute T:System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute +T:System.Diagnostics.CodeAnalysis.MemberNotNullAttribute T:System.Diagnostics.CodeAnalysis.SuppressMessageAttribute T:System.Diagnostics.DebuggerBrowsableAttribute T:System.Diagnostics.DebuggerDisplayAttribute diff --git a/src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs b/src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs index eed8ccb978a81..254c15c44c0fb 100644 --- a/src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs +++ b/src/libraries/Common/src/System/Net/DebugCriticalHandleMinusOneIsInvalid.cs @@ -14,20 +14,14 @@ namespace System.Net // internal abstract class DebugCriticalHandleMinusOneIsInvalid : CriticalHandleMinusOneIsInvalid { - private string _trace = null!; + private string _trace; protected DebugCriticalHandleMinusOneIsInvalid() : base() - { - Trace(); - } - - private void Trace() { _trace = "WARNING! GC-ed >>" + this.GetType().FullName + "<< (should be explicitly closed) \r\n"; if (NetEventSource.IsEnabled) NetEventSource.Info(this, "Creating SafeHandle"); #if TRACE_VERBOSE - string stacktrace = Environment.StackTrace; - _trace += stacktrace; + _trace += Environment.StackTrace; #endif //TRACE_VERBOSE } diff --git a/src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs b/src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs index 0d993cd60d738..fe594f12edd2f 100644 --- a/src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs +++ b/src/libraries/Common/src/System/Net/DebugCriticalHandleZeroOrMinusOneIsInvalid.cs @@ -14,20 +14,14 @@ namespace System.Net // internal abstract class DebugCriticalHandleZeroOrMinusOneIsInvalid : CriticalHandleZeroOrMinusOneIsInvalid { - private string _trace = null!; + private string _trace; protected DebugCriticalHandleZeroOrMinusOneIsInvalid() : base() - { - Trace(); - } - - private void Trace() { _trace = "WARNING! GC-ed >>" + this.GetType().FullName + "<< (should be explicitly closed) \r\n"; if (NetEventSource.IsEnabled) NetEventSource.Info(this, "Creating SafeHandle"); #if TRACE_VERBOSE - string stacktrace = Environment.StackTrace; - _trace += stacktrace; + _trace += Environment.StackTrace; #endif //TRACE_VERBOSE } diff --git a/src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs b/src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs index 4fd2c5b4e9850..633ea98f90b28 100644 --- a/src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs +++ b/src/libraries/Common/src/System/Net/DebugSafeHandleMinusOneIsInvalid.cs @@ -14,20 +14,14 @@ namespace System.Net // internal abstract class DebugSafeHandleMinusOneIsInvalid : SafeHandleMinusOneIsInvalid { - private string _trace = null!; // initialized by helper called from ctor + private string _trace; protected DebugSafeHandleMinusOneIsInvalid(bool ownsHandle) : base(ownsHandle) - { - Trace(); - } - - private void Trace() { _trace = "WARNING! GC-ed >>" + this.GetType().FullName + "<< (should be explicitly closed) \r\n"; if (NetEventSource.IsEnabled) NetEventSource.Info(this, "Creating SafeHandle"); #if TRACE_VERBOSE - string stacktrace = Environment.StackTrace; - _trace += stacktrace; + _trace += Environment.StackTrace; #endif //TRACE_VERBOSE } diff --git a/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs b/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs index 9263131f72021..0149545a9ff22 100644 --- a/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs +++ b/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs @@ -24,7 +24,7 @@ internal partial class NTAuthentication private ContextFlagsPal _contextFlags; private bool _isCompleted; - private string _package = null!; + private string _package; private string? _lastProtocolName; private string? _protocolName; private string? _clientSpecifiedSpn; @@ -98,6 +98,7 @@ internal NTAuthentication(bool isServer, string package, NetworkCredential crede Initialize(isServer, package, credential, spn, requestedContextFlags, channelBinding); } + [MemberNotNull(nameof(_package))] private void Initialize(bool isServer, string package, NetworkCredential credential, string? spn, ContextFlagsPal requestedContextFlags, ChannelBinding? channelBinding) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this, package, spn, requestedContextFlags); diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs index 1939dd9d68b29..3b7f8023f0430 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/BlockingCollection.cs @@ -43,14 +43,14 @@ namespace System.Collections.Concurrent [DebuggerDisplay("Count = {Count}, Type = {_collection}")] public class BlockingCollection : IEnumerable, ICollection, IDisposable, IReadOnlyCollection { - private IProducerConsumerCollection _collection = null!; + private IProducerConsumerCollection _collection; private int _boundedCapacity; private const int NON_BOUNDED = -1; private SemaphoreSlim? _freeNodes; - private SemaphoreSlim _occupiedNodes = null!; + private SemaphoreSlim _occupiedNodes; private bool _isDisposed; - private CancellationTokenSource _consumersCancellationTokenSource = null!; - private CancellationTokenSource _producersCancellationTokenSource = null!; + private CancellationTokenSource _consumersCancellationTokenSource; + private CancellationTokenSource _producersCancellationTokenSource; private volatile int _currentAdders; private const int COMPLETE_ADDING_ON_MASK = unchecked((int)0x80000000); @@ -211,6 +211,10 @@ public BlockingCollection(IProducerConsumerCollection collection) /// The collection to use as the underlying data store. /// The bounded size of the collection. /// The number of items currently in the underlying collection. + [MemberNotNull(nameof(_collection))] + [MemberNotNull(nameof(_consumersCancellationTokenSource))] + [MemberNotNull(nameof(_producersCancellationTokenSource))] + [MemberNotNull(nameof(_occupiedNodes))] private void Initialize(IProducerConsumerCollection collection, int boundedCapacity, int collectionCount) { Debug.Assert(boundedCapacity > 0 || boundedCapacity == NON_BOUNDED); diff --git a/src/libraries/System.Collections.Specialized/src/System/Collections/Specialized/NameObjectCollectionBase.cs b/src/libraries/System.Collections.Specialized/src/System/Collections/Specialized/NameObjectCollectionBase.cs index 19de422d40ba9..8d4b37f56ae9e 100644 --- a/src/libraries/System.Collections.Specialized/src/System/Collections/Specialized/NameObjectCollectionBase.cs +++ b/src/libraries/System.Collections.Specialized/src/System/Collections/Specialized/NameObjectCollectionBase.cs @@ -11,6 +11,7 @@ #pragma warning disable 618 // obsolete types, namely IHashCodeProvider +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.Serialization; @@ -24,9 +25,9 @@ namespace System.Collections.Specialized public abstract class NameObjectCollectionBase : ICollection, ISerializable, IDeserializationCallback { private bool _readOnly = false; - private ArrayList _entriesArray = null!; // initialized in Reset method, called from constructor + private ArrayList _entriesArray; private IEqualityComparer _keyComparer; - private volatile Hashtable _entriesTable = null!; // initialized in Reset method, called from constructor + private volatile Hashtable _entriesTable; private volatile NameObjectEntry? _nullKeyEntry; private KeysCollection? _keys; private int _version; @@ -96,6 +97,8 @@ public virtual void OnDeserialization(object? sender) // Private helpers // + [MemberNotNull(nameof(_entriesArray))] + [MemberNotNull(nameof(_entriesTable))] private void Reset() { _entriesArray = new ArrayList(); @@ -104,6 +107,8 @@ private void Reset() _version++; } + [MemberNotNull(nameof(_entriesArray))] + [MemberNotNull(nameof(_entriesTable))] private void Reset(int capacity) { _entriesArray = new ArrayList(capacity); diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs index e810859890653..563f2dcb5b68f 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs @@ -25,7 +25,7 @@ public class AssemblyCatalog : ComposablePartCatalog, ICompositionElement { private readonly object _thisLock = new object(); private readonly ICompositionElement _definitionOrigin; - private volatile Assembly _assembly = null!; // Always initiialized with helper + private volatile Assembly _assembly; private volatile ComposablePartCatalog? _innerCatalog = null; private int _isDisposed = 0; @@ -387,6 +387,7 @@ public AssemblyCatalog(Assembly assembly, ICompositionElement definitionOrigin) _definitionOrigin = definitionOrigin; } + [MemberNotNull(nameof(_assembly))] private void InitializeAssemblyCatalog(Assembly assembly) { if (assembly.ReflectionOnly) diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs index 16fffd4582b15..4a293f66a0791 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs @@ -23,16 +23,16 @@ namespace System.ComponentModel.Composition.Hosting public partial class DirectoryCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged, ICompositionElement { private readonly Lock _thisLock = new Lock(); - private readonly ICompositionElement? _definitionOrigin = null; - private ComposablePartCatalogCollection _catalogCollection = null!; // Always initialized with Initialize() - private Dictionary _assemblyCatalogs = null!; - private volatile bool _isDisposed = false; - private string _path = null!; - private string _fullPath = null!; - private string _searchPattern = null!; - private ReadOnlyCollection _loadedFiles = null!; + private readonly ICompositionElement? _definitionOrigin; + private ComposablePartCatalogCollection _catalogCollection; + private Dictionary _assemblyCatalogs; + private volatile bool _isDisposed; + private string _path; + private string _fullPath; + private string _searchPattern; + private ReadOnlyCollection _loadedFiles; - private readonly ReflectionContext? _reflectionContext = null; + private readonly ReflectionContext? _reflectionContext; /// /// Creates a catalog of s based on all the *.dll files @@ -745,6 +745,12 @@ private static string GetFullPath(string path) return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? fullPath.ToUpperInvariant() : fullPath; } + [MemberNotNull(nameof(_path))] + [MemberNotNull(nameof(_fullPath))] + [MemberNotNull(nameof(_searchPattern))] + [MemberNotNull(nameof(_assemblyCatalogs))] + [MemberNotNull(nameof(_catalogCollection))] + [MemberNotNull(nameof(_loadedFiles))] private void Initialize(string path, string searchPattern) { _path = path; diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ImportType.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ImportType.cs index 0f02be5bb1d2e..4c322cfcfae34 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ImportType.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ImportType.cs @@ -18,7 +18,7 @@ internal class ImportType private readonly Type _type; private readonly bool _isAssignableCollectionType; - private Type _contractType = null!; // Initialized in Initialize() + private Type _contractType; private Func? _castSingleValue; private readonly bool _isOpenGeneric = false; @@ -129,6 +129,7 @@ public static bool IsDescendentOf(Type type, Type baseType) return IsGenericDescendentOf(type, baseType.GetGenericTypeDefinition()); } + [MemberNotNull(nameof(_contractType))] private void Initialize(Type type) { if (!type.IsGenericType) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index 8d7fffa020357..e3a7f04590694 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -92,7 +92,7 @@ public partial class Activity : IDisposable /// reasonable, but arguments (e.g. specific accounts etc), should not be in /// the name but rather in the tags. /// - public string OperationName { get; } = null!; + public string OperationName { get; } /// Gets or sets the display name of the Activity /// @@ -334,7 +334,6 @@ public Activity(string operationName) if (string.IsNullOrEmpty(operationName)) { NotifyError(new ArgumentException(SR.OperationNameInvalid)); - return; } OperationName = operationName; diff --git a/src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs b/src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs index 3eec27d88268d..369f66283ae0e 100644 --- a/src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/Microsoft/Win32/SafeHandles/SafeProcessHandle.Unix.cs @@ -12,6 +12,7 @@ ===========================================================*/ using System; +using System.Diagnostics; namespace Microsoft.Win32.SafeHandles { @@ -24,7 +25,7 @@ public sealed partial class SafeProcessHandle : SafeHandleZeroOrMinusOneIsInvali // Process.{Safe}Handle to initalize and use a WaitHandle to successfully use it on // Unix as well to wait for the process to complete. - private readonly SafeWaitHandle _handle = null!; + private readonly SafeWaitHandle? _handle; private readonly bool _releaseRef; internal SafeProcessHandle(int processId, SafeWaitHandle handle) : @@ -41,6 +42,7 @@ protected override bool ReleaseHandle() { if (_releaseRef) { + Debug.Assert(_handle != null); _handle.DangerousRelease(); } return true; diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/PerformanceCounterLib.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/PerformanceCounterLib.cs index 354acdffeb49c..c9b03aead5ce3 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/PerformanceCounterLib.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/PerformanceCounterLib.cs @@ -9,6 +9,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Threading; @@ -192,19 +193,22 @@ private Dictionary GetStringTable(bool isHelp) internal class PerformanceMonitor { #if FEATURE_REGISTRY - private RegistryKey _perfDataKey = null!; // will be initialized by Init() method + private RegistryKey _perfDataKey; #endif private readonly string _machineName; internal PerformanceMonitor(string machineName) { _machineName = machineName; +#if FEATURE_REGISTRY Init(); +#endif } +#if FEATURE_REGISTRY + [MemberNotNull(nameof(_perfDataKey))] private void Init() { -#if FEATURE_REGISTRY if (ProcessManager.IsRemoteMachine(_machineName)) { _perfDataKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.PerformanceData, _machineName); @@ -213,8 +217,8 @@ private void Init() { _perfDataKey = Registry.PerformanceData; } -#endif } +#endif // Win32 RegQueryValueEx for perf data could deadlock (for a Mutex) up to 2mins in some // scenarios before they detect it and exit gracefully. In the mean time, ERROR_BUSY, diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SourceFilter.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SourceFilter.cs index e150ca4e22679..de4deb3ea7d95 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SourceFilter.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SourceFilter.cs @@ -4,12 +4,13 @@ using System; using System.Collections; +using System.Diagnostics.CodeAnalysis; namespace System.Diagnostics { public class SourceFilter : TraceFilter { - private string _src = null!; + private string _src; public SourceFilter(string source) { @@ -31,6 +32,7 @@ public string Source { return _src; } + [MemberNotNull(nameof(_src))] set { if (value == null) diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SwitchAttribute.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SwitchAttribute.cs index 56bf0770eaf3d..9355004d23bd1 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SwitchAttribute.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SwitchAttribute.cs @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Reflection; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; namespace System.Diagnostics { @@ -12,8 +12,8 @@ namespace System.Diagnostics AttributeTargets.Event | AttributeTargets.Method | AttributeTargets.Property)] public sealed class SwitchAttribute : Attribute { - private Type _type = null!; // Initialized using property - private string _name = null!; + private Type _type; + private string _name; public SwitchAttribute(string switchName, Type switchType) { @@ -24,6 +24,7 @@ public SwitchAttribute(string switchName, Type switchType) public string SwitchName { get { return _name; } + [MemberNotNull(nameof(_name))] set { if (value == null) @@ -38,6 +39,7 @@ public string SwitchName public Type SwitchType { get { return _type; } + [MemberNotNull(nameof(_type))] set { if (value == null) diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SwitchLevelAttribute.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SwitchLevelAttribute.cs index dc659683f0565..caa207b318b60 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SwitchLevelAttribute.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/SwitchLevelAttribute.cs @@ -2,12 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Diagnostics { [AttributeUsage(AttributeTargets.Class)] public sealed class SwitchLevelAttribute : Attribute { - private Type _type = null!; + private Type _type; public SwitchLevelAttribute(Type switchLevelType) { @@ -17,6 +19,7 @@ public SwitchLevelAttribute(Type switchLevelType) public Type SwitchLevelType { get { return _type; } + [MemberNotNull(nameof(_type))] set { if (value == null) diff --git a/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs b/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs index 4c91c651b28e4..b3d2f096545f4 100644 --- a/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs +++ b/src/libraries/System.Drawing.Common/ref/System.Drawing.Common.cs @@ -305,7 +305,7 @@ public Font(string familyName, float emSize, System.Drawing.GraphicsUnit unit) { [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)] public string Name { get { throw null; } } [System.ComponentModel.BrowsableAttribute(false)] - public string OriginalFontName { get { throw null; } } + public string? OriginalFontName { get { throw null; } } public float Size { get { throw null; } } [System.ComponentModel.BrowsableAttribute(false)] public float SizeInPoints { get { throw null; } } diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs index bbabbf88ed0b8..5bf4ebb240504 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs @@ -29,7 +29,7 @@ public sealed partial class Font : MarshalByRefObject, ICloneable, IDisposable, private byte _gdiCharSet = SafeNativeMethods.DEFAULT_CHARSET; private bool _gdiVerticalFont; private string _systemFontName = ""; - private string _originalFontName = null!; + private string? _originalFontName; // Return value is in Unit (the unit the font was created in) /// @@ -108,7 +108,7 @@ public sealed partial class Font : MarshalByRefObject, ICloneable, IDisposable, /// This property is required by the framework and not intended to be used directly. /// [Browsable(false)] - public string OriginalFontName => _originalFontName; + public string? OriginalFontName => _originalFontName; /// /// Gets the name of this . diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs index 9114fe44f72df..1e82f12a3b2a2 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -14,7 +15,7 @@ public partial class DeflateStream : Stream { private const int DefaultBufferSize = 8192; - private Stream _stream = null!; // field initialized in init methods called from constructor + private Stream _stream; private CompressionMode _mode; private bool _leaveOpen; private Inflater? _inflater; @@ -89,6 +90,7 @@ internal DeflateStream(Stream stream, CompressionLevel compressionLevel, bool le /// /// Sets up this DeflateStream to be used for Zlib Deflation/Compression /// + [MemberNotNull(nameof(_stream))] internal void InitializeDeflater(Stream stream, bool leaveOpen, int windowBits, CompressionLevel compressionLevel) { Debug.Assert(stream != null); diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/Inflater.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/Inflater.cs index 78fcd17f34c54..7fda017b16b0e 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/Inflater.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/Inflater.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Security; @@ -18,8 +19,8 @@ internal sealed class Inflater : IDisposable private bool _finished; // Whether the end of the stream has been reached private bool _isDisposed; // Prevents multiple disposals - private readonly int _windowBits; // The WindowBits parameter passed to Inflater construction - private ZLibNative.ZLibStreamHandle _zlibStream = null!; // The handle to the primary underlying zlib stream, initialized by a method that is called from the constructor + private readonly int _windowBits; // The WindowBits parameter passed to Inflater construction + private ZLibNative.ZLibStreamHandle _zlibStream; // The handle to the primary underlying zlib stream private GCHandle _inputBufferHandle; // The handle to the buffer that provides input to _zlibStream private readonly long _uncompressedSize; private long _currentInflatedCount; @@ -222,6 +223,7 @@ public void Dispose() /// /// Creates the ZStream that will handle inflation. /// + [MemberNotNull(nameof(_zlibStream))] private void InflateInit(int windowBits) { ZLibNative.ErrorCode error; diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs index 866e1ab2a4feb..925a59082afef 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs @@ -36,8 +36,8 @@ public partial class ZipArchiveEntry private bool _everOpenedForWrite; private Stream? _outstandingWriteStream; private uint _externalFileAttr; - private string _storedEntryName = null!; // indirectly set in constructor using FullName property - private byte[] _storedEntryNameBytes = null!; + private string _storedEntryName; + private byte[] _storedEntryNameBytes; // only apply to update mode private List? _cdUnknownExtraFields; private List? _lhUnknownExtraFields; @@ -185,6 +185,8 @@ public string FullName return _storedEntryName; } + [MemberNotNull(nameof(_storedEntryNameBytes))] + [MemberNotNull(nameof(_storedEntryName))] private set { if (value == null) diff --git a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs index 1d13427bb6659..07540cc0f338b 100644 --- a/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs +++ b/src/libraries/System.IO.IsolatedStorage/src/System/IO/IsolatedStorage/IsolatedStorageFile.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; @@ -14,12 +15,12 @@ public sealed partial class IsolatedStorageFile : IsolatedStorage, IDisposable internal const string s_files = "Files"; internal const string s_assemFiles = "AssemFiles"; internal const string s_appFiles = "AppFiles"; - private string _rootDirectory = null!; // Initialized in helper private bool _disposed; private bool _closed; private readonly object _internalLock = new object(); + private readonly string _rootDirectory; // Data file notes // =============== @@ -35,7 +36,36 @@ public sealed partial class IsolatedStorageFile : IsolatedStorage, IDisposable // private const string InfoFile = "info.dat"; // private const string AppInfoFile = "appInfo.dat"; - internal IsolatedStorageFile() { } + internal IsolatedStorageFile(IsolatedStorageScope scope) + { + // Evidence isn't currently available: https://github.com/dotnet/runtime/issues/18208 + // public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, Evidence domainEvidence, Type domainEvidenceType, Evidence assemblyEvidence, Type assemblyEvidenceType) { return default(IsolatedStorageFile); } + + // InitStore will set up the IdentityHash + InitStore(scope, null, null); + + StringBuilder sb = new StringBuilder(Helper.GetRootDirectory(scope)); + sb.Append(SeparatorExternal); + sb.Append(IdentityHash); + sb.Append(SeparatorExternal); + + if (Helper.IsApplication(scope)) + { + sb.Append(s_appFiles); + } + else if (Helper.IsDomain(scope)) + { + sb.Append(s_files); + } + else + { + sb.Append(s_assemFiles); + } + sb.Append(SeparatorExternal); + + _rootDirectory = sb.ToString(); + Helper.CreateDirectory(_rootDirectory, scope); + } // Using this property to match .NET Framework for testing private string RootDirectory @@ -586,9 +616,7 @@ public static IsolatedStorageFile GetMachineStoreForDomain() private static IsolatedStorageFile GetStore(IsolatedStorageScope scope) { - IsolatedStorageFile isf = new IsolatedStorageFile(); - isf.Initialize(scope); - return isf; + return new IsolatedStorageFile(scope); } // Notes on the GetStore methods: @@ -633,38 +661,6 @@ public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, object? d return (domainIdentity == null && assemblyIdentity == null) ? GetStore(scope) : throw new PlatformNotSupportedException(SR.PlatformNotSupported_CAS); // https://github.com/dotnet/runtime/issues/18208 } - // https://github.com/dotnet/runtime/issues/18208 - // Evidence isn't currently available - // public static IsolatedStorageFile GetStore(IsolatedStorageScope scope, Evidence domainEvidence, Type domainEvidenceType, Evidence assemblyEvidence, Type assemblyEvidenceType) { return default(IsolatedStorageFile); } - - private void Initialize(IsolatedStorageScope scope) - { - // InitStore will set up the IdentityHash - InitStore(scope, null, null); - - StringBuilder sb = new StringBuilder(Helper.GetRootDirectory(scope)); - sb.Append(SeparatorExternal); - sb.Append(IdentityHash); - sb.Append(SeparatorExternal); - - if (Helper.IsApplication(scope)) - { - sb.Append(s_appFiles); - } - else if (Helper.IsDomain(scope)) - { - sb.Append(s_files); - } - else - { - sb.Append(s_assemFiles); - } - sb.Append(SeparatorExternal); - - _rootDirectory = sb.ToString(); - Helper.CreateDirectory(_rootDirectory, scope); - } - internal string GetFullPath(string partialPath) { Debug.Assert(partialPath != null, "partialPath should be non null"); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs index a76798fbe0c59..e948fcf06e60c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestMessage.cs @@ -19,10 +19,10 @@ public class HttpRequestMessage : IDisposable // The message shouldn't be sent again if this field is equal to MessageAlreadySent. private int _sendStatus = MessageNotYetSent; - private HttpMethod _method = null!; + private HttpMethod _method; private Uri? _requestUri; private HttpRequestHeaders? _headers; - private Version _version = null!; + private Version _version; private HttpContent? _content; private bool _disposed; private IDictionary? _properties; @@ -177,6 +177,8 @@ public override string ToString() return sb.ToString(); } + [MemberNotNull(nameof(_method))] + [MemberNotNull(nameof(_version))] private void InitializeValues(HttpMethod method, Uri? requestUri) { if (method == null) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs index c4e4e80e1d247..9ccda2b0ee14a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -11,7 +12,7 @@ namespace System.Net.Http { public class StreamContent : HttpContent { - private Stream _content = null!; // Initialized in helper + private Stream _content; private int _bufferSize; private bool _contentConsumed; private long _start; @@ -41,6 +42,7 @@ public StreamContent(Stream content, int bufferSize) InitializeContent(content, bufferSize); } + [MemberNotNull(nameof(_content))] private void InitializeContent(Stream content, int bufferSize) { _content = content; diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs index c68dc8185e5c4..ae58a9892f054 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpClient.cs @@ -44,17 +44,17 @@ public class SmtpClient : IDisposable private SmtpDeliveryMethod _deliveryMethod = SmtpDeliveryMethod.Network; private SmtpDeliveryFormat _deliveryFormat = SmtpDeliveryFormat.SevenBit; // Non-EAI default private string? _pickupDirectoryLocation; - private SmtpTransport _transport = null!; // initialized by helper called from ctor + private SmtpTransport _transport; private MailMessage? _message; //required to prevent premature finalization private MailWriter? _writer; private MailAddressCollection? _recipients; - private SendOrPostCallback _onSendCompletedDelegate = null!; // initialized by helper called from ctor + private SendOrPostCallback _onSendCompletedDelegate; private Timer? _timer; private ContextAwareResult? _operationCompletedResult; private AsyncOperation? _asyncOp; private static readonly AsyncCallback s_contextSafeCompleteCallback = new AsyncCallback(ContextSafeCompleteCallback); private const int DefaultPort = 25; - internal string _clientDomain = null!; // initialized by helper called from ctor + internal string _clientDomain; private bool _disposed; private ServicePoint? _servicePoint; // (async only) For when only some recipients fail. We still send the e-mail to the others. @@ -112,6 +112,9 @@ public SmtpClient(string? host, int port) } } + [MemberNotNull(nameof(_transport))] + [MemberNotNull(nameof(_onSendCompletedDelegate))] + [MemberNotNull(nameof(_clientDomain))] private void Initialize() { _transport = new SmtpTransport(this); diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs index 891d17ef06882..33618989e8b96 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentDisposition.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Collections.Specialized; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Net.Mail; using System.Text; @@ -20,7 +21,7 @@ public class ContentDisposition private TrackingValidationObjectDictionary? _parameters; private string _disposition; - private string _dispositionType = null!; // set by ctor or by helper called from ctor + private string _dispositionType; private bool _isChanged; private bool _isPersisted; @@ -259,6 +260,7 @@ public override bool Equals(object? rparam) public override int GetHashCode() => ToString().ToLowerInvariant().GetHashCode(); + [MemberNotNull(nameof(_dispositionType))] private void ParseValue() { int offset = 0; diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs index 7394cfdd20c5e..009a7edaf013b 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/ContentType.cs @@ -24,8 +24,8 @@ public class ContentType { private readonly TrackingStringDictionary _parameters = new TrackingStringDictionary(); - private string _mediaType = null!; // initialized by helper called from ctor - private string _subType = null!; // initialized by helper called from ctor + private string _mediaType; + private string _subType; private bool _isChanged; private string _type; private bool _isPersisted; @@ -231,86 +231,71 @@ public override bool Equals(object? rparam) => public override int GetHashCode() => ToString().ToLowerInvariant().GetHashCode(); // Helper methods. - + [MemberNotNull(nameof(_mediaType))] + [MemberNotNull(nameof(_subType))] private void ParseValue() { - int offset = 0; - Exception? exception = null; - try { + int offset = 0; + _mediaType = MailBnfHelper.ReadToken(_type, ref offset, null); if (_mediaType == null || _mediaType.Length == 0 || offset >= _type.Length || _type[offset++] != '/') { - exception = new FormatException(SR.ContentTypeInvalid); + throw new FormatException(SR.ContentTypeInvalid); } - if (exception == null) + _subType = MailBnfHelper.ReadToken(_type, ref offset, null); + if (_subType == null || _subType.Length == 0) { - _subType = MailBnfHelper.ReadToken(_type, ref offset, null); - if (_subType == null || _subType.Length == 0) - { - exception = new FormatException(SR.ContentTypeInvalid); - } + throw new FormatException(SR.ContentTypeInvalid); } - if (exception == null) + while (MailBnfHelper.SkipCFWS(_type, ref offset)) { - while (MailBnfHelper.SkipCFWS(_type, ref offset)) + if (_type[offset++] != ';') { - if (_type[offset++] != ';') - { - exception = new FormatException(SR.ContentTypeInvalid); - break; - } - - if (!MailBnfHelper.SkipCFWS(_type, ref offset)) - { - break; - } - - string? paramAttribute = MailBnfHelper.ReadParameterAttribute(_type, ref offset, null); - - if (paramAttribute == null || paramAttribute.Length == 0) - { - exception = new FormatException(SR.ContentTypeInvalid); - break; - } - - string? paramValue; - if (offset >= _type.Length || _type[offset++] != '=') - { - exception = new FormatException(SR.ContentTypeInvalid); - break; - } - - if (!MailBnfHelper.SkipCFWS(_type, ref offset)) - { - exception = new FormatException(SR.ContentTypeInvalid); - break; - } - - paramValue = _type[offset] == '"' ? - MailBnfHelper.ReadQuotedString(_type, ref offset, null) : - MailBnfHelper.ReadToken(_type, ref offset, null); - - if (paramValue == null) - { - exception = new FormatException(SR.ContentTypeInvalid); - break; - } - - _parameters.Add(paramAttribute, paramValue); + throw new FormatException(SR.ContentTypeInvalid); } + + if (!MailBnfHelper.SkipCFWS(_type, ref offset)) + { + break; + } + + string? paramAttribute = MailBnfHelper.ReadParameterAttribute(_type, ref offset, null); + + if (paramAttribute == null || paramAttribute.Length == 0) + { + throw new FormatException(SR.ContentTypeInvalid); + } + + string? paramValue; + if (offset >= _type.Length || _type[offset++] != '=') + { + throw new FormatException(SR.ContentTypeInvalid); + } + + if (!MailBnfHelper.SkipCFWS(_type, ref offset)) + { + throw new FormatException(SR.ContentTypeInvalid); + } + + paramValue = _type[offset] == '"' ? + MailBnfHelper.ReadQuotedString(_type, ref offset, null) : + MailBnfHelper.ReadToken(_type, ref offset, null); + + if (paramValue == null) + { + throw new FormatException(SR.ContentTypeInvalid); + } + + _parameters.Add(paramAttribute, paramValue); } + _parameters.IsChanged = false; } - catch (FormatException) - { - throw new FormatException(SR.ContentTypeInvalid); - } - - if (exception != null) + catch (FormatException fe) when (fe.Message != SR.ContentTypeInvalid) { throw new FormatException(SR.ContentTypeInvalid); } diff --git a/src/libraries/System.Net.Primitives/src/System/Net/NetworkCredential.cs b/src/libraries/System.Net.Primitives/src/System/Net/NetworkCredential.cs index 04186f27adbed..5f7fc71a3899b 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/NetworkCredential.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/NetworkCredential.cs @@ -16,7 +16,7 @@ namespace System.Net /// public class NetworkCredential : ICredentials, ICredentialsByHost { - private string _domain = null!; + private string _domain; private string _userName = string.Empty; private object? _password; @@ -132,6 +132,7 @@ public SecureString SecurePassword public string Domain { get { return _domain; } + [MemberNotNull(nameof(_domain))] set { _domain = value ?? string.Empty; } } diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs index 8515b343613fe..b1941c136d78b 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -37,7 +38,7 @@ private enum SingleBufferHandleState : byte { None, InProcess, Set } private FileStream[]? _sendPacketsFileStreams; // Overlapped object related variables. - private PreAllocatedOverlapped _preAllocatedOverlapped = null!; // initialized by helper called from ctor + private PreAllocatedOverlapped _preAllocatedOverlapped; private readonly StrongBox _strongThisRef = new StrongBox(); // state for _preAllocatedOverlapped; .Value set to this while operations in flight // Cancellation support @@ -47,6 +48,7 @@ private enum SingleBufferHandleState : byte { None, InProcess, Set } private PinState _pinState; private enum PinState : byte { None = 0, MultipleBuffer, SendPackets } + [MemberNotNull(nameof(_preAllocatedOverlapped))] private void InitializeInternals() { // PreAllocatedOverlapped captures ExecutionContext, but SocketAsyncEventArgs ensures diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.cs index e601d637ab0a0..6919d450c8616 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.cs @@ -6,6 +6,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -84,8 +85,8 @@ public sealed partial class private unsafe int* _nameHashesPtr; // In case we're using UnmanagedMemoryStream private int[]? _namePositions; // relative locations of names private unsafe int* _namePositionsPtr; // If we're using UnmanagedMemoryStream - private Type?[] _typeTable = null!; // Lazy array of Types for resource values. - private int[] _typeNamePositions = null!; // To delay initialize type table + private Type?[] _typeTable; // Lazy array of Types for resource values. + private int[] _typeNamePositions; // To delay initialize type table private int _numResources; // Num of resources files, in case arrays aren't allocated. // We'll include a separate code path that uses UnmanagedMemoryStream to @@ -739,6 +740,8 @@ private unsafe string AllocateStringForNameIndex(int index, out int dataOffset) // Reads in the header information for a .resources file. Verifies some // of the assumptions about this resource set, and builds the class table // for the default resource file format. + [MemberNotNull(nameof(_typeTable))] + [MemberNotNull(nameof(_typeNamePositions))] private void ReadResources() { Debug.Assert(_store != null, "ResourceReader is closed!"); @@ -759,6 +762,8 @@ private void ReadResources() } } + [MemberNotNull(nameof(_typeTable))] + [MemberNotNull(nameof(_typeNamePositions))] private void _ReadResources() { // Read ResourceManager header diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACE.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACE.cs index e33cbaa0d9dee..8b895791b719d 100644 --- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACE.cs +++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACE.cs @@ -649,7 +649,7 @@ public abstract class KnownAce : GenericAce // private int _accessMask; - private SecurityIdentifier _sid = null!; // Initialized in constructor using property + private SecurityIdentifier _sid; #endregion @@ -711,7 +711,7 @@ public SecurityIdentifier SecurityIdentifier { return _sid; } - + [MemberNotNull(nameof(_sid))] set { if (value == null) diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs index 2a65e0a0b09aa..5534bffb4809a 100644 --- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs +++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs @@ -13,6 +13,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Security.Principal; namespace System.Security.AccessControl @@ -234,7 +235,7 @@ public sealed class RawAcl : GenericAcl #region Private Members private byte _revision; - private List _aces = null!; // Initialized in helper + private List _aces; #endregion @@ -315,6 +316,7 @@ private void MarshalHeader(byte[] binaryForm, int offset) binaryForm[offset + 7] = 0; } + [MemberNotNull(nameof(_aces))] internal void SetBinaryForm(byte[] binaryForm, int offset) { int count, length; diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/SecurityDescriptor.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/SecurityDescriptor.cs index 81c74ad57a63a..e28c2f91503d9 100644 --- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/SecurityDescriptor.cs +++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/SecurityDescriptor.cs @@ -11,11 +11,13 @@ using Microsoft.Win32; using System; +using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; using System.Security.Principal; -using System.ComponentModel; + namespace System.Security.AccessControl { [Flags] @@ -824,7 +826,7 @@ public sealed class CommonSecurityDescriptor : GenericSecurityDescriptor private bool _isContainer; private bool _isDS; - private RawSecurityDescriptor _rawSd = null!; // Initialized in helper. + private RawSecurityDescriptor _rawSd; private SystemAcl? _sacl; private DiscretionaryAcl? _dacl; @@ -832,7 +834,7 @@ public sealed class CommonSecurityDescriptor : GenericSecurityDescriptor #endregion #region Private Methods - + [MemberNotNull(nameof(_rawSd))] private void CreateFromParts(bool isContainer, bool isDS, ControlFlags flags, SecurityIdentifier? owner, SecurityIdentifier? group, SystemAcl? systemAcl, DiscretionaryAcl? discretionaryAcl) { if (systemAcl != null && diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AppleCCCryptor.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AppleCCCryptor.cs index fec06f96676be..1df1ca4254069 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AppleCCCryptor.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/AppleCCCryptor.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; namespace Internal.Cryptography @@ -11,7 +12,7 @@ namespace Internal.Cryptography internal sealed class AppleCCCryptor : BasicSymmetricCipher { private readonly bool _encrypting; - private SafeAppleCryptorHandle _cryptor = null!; + private SafeAppleCryptorHandle _cryptor; public AppleCCCryptor( Interop.AppleCrypto.PAL_SymmetricAlgorithm algorithm, @@ -141,6 +142,7 @@ private unsafe int CipherUpdate(byte[] input, int inputOffset, int count, byte[] return bytesWritten; } + [MemberNotNull(nameof(_cryptor))] private unsafe void OpenCryptor( Interop.AppleCrypto.PAL_SymmetricAlgorithm algorithm, CipherMode cipherMode, diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HMACCommon.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HMACCommon.cs index 03108011b709d..d0aebd8cd277a 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HMACCommon.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HMACCommon.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace Internal.Cryptography { @@ -17,26 +18,26 @@ namespace Internal.Cryptography // internal sealed class HMACCommon { - public HMACCommon(string hashAlgorithmId, byte[] key, int blockSize) : this(hashAlgorithmId, blockSize) + public HMACCommon(string hashAlgorithmId, byte[] key, int blockSize) : + this(hashAlgorithmId, (ReadOnlySpan)key, blockSize) { - ChangeKey(key); + // If the key is smaller than the block size, the delegated ctor won't have initialized ActualKey, + // so set it here as would ChangeKey. + ActualKey ??= key; } - internal HMACCommon(string hashAlgorithmId, ReadOnlySpan key, int blockSize) : this(hashAlgorithmId, blockSize) - { - // note: will not set ActualKey if key size is smaller or equal than blockSize - // this is to avoid extra allocation. ActualKey can still be used if key is generated. - // Otherwise the ReadOnlySpan overload would actually be slower than byte array overload. - ChangeKey(key); - } - - private HMACCommon(string hashAlgorithmId, int blockSize) + internal HMACCommon(string hashAlgorithmId, ReadOnlySpan key, int blockSize) { Debug.Assert(!string.IsNullOrEmpty(hashAlgorithmId)); Debug.Assert(blockSize > 0 || blockSize == -1); _hashAlgorithmId = hashAlgorithmId; _blockSize = blockSize; + + // note: will not set ActualKey if key size is smaller or equal than blockSize + // this is to avoid extra allocation. ActualKey can still be used if key is generated. + // Otherwise the ReadOnlySpan overload would actually be slower than byte array overload. + ActualKey = ChangeKeyImpl(key); } public int HashSizeInBits => _hMacProvider.HashSizeInBytes * 8; @@ -46,12 +47,7 @@ public void ChangeKey(byte[] key) ActualKey = ChangeKeyImpl(key) ?? key; } - internal void ChangeKey(ReadOnlySpan key) - { - // note: does not set key when it's smaller than blockSize - ActualKey = ChangeKeyImpl(key); - } - + [MemberNotNull(nameof(_hMacProvider))] private byte[]? ChangeKeyImpl(ReadOnlySpan key) { byte[]? modifiedKey = null; @@ -69,7 +65,7 @@ internal void ChangeKey(ReadOnlySpan key) modifiedKey = _lazyHashProvider.FinalizeHashAndReset(); } - HashProvider oldHashProvider = _hMacProvider; + HashProvider? oldHashProvider = _hMacProvider; _hMacProvider = null!; oldHashProvider?.Dispose(true); _hMacProvider = HashProviderDispenser.CreateMacProvider(_hashAlgorithmId, key); @@ -105,7 +101,7 @@ public void Dispose(bool disposing) } private readonly string _hashAlgorithmId; - private HashProvider _hMacProvider = null!; // Initialized in helper + private HashProvider _hMacProvider; private volatile HashProvider? _lazyHashProvider; private readonly int _blockSize; } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs index b43bfbcc138ac..eb559e0cb9b3f 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/OpenSslCipher.cs @@ -5,6 +5,7 @@ using System; using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Security.Cryptography; using Microsoft.Win32.SafeHandles; @@ -14,7 +15,7 @@ namespace Internal.Cryptography internal class OpenSslCipher : BasicSymmetricCipher { private readonly bool _encrypting; - private SafeEvpCipherCtxHandle _ctx = null!; + private SafeEvpCipherCtxHandle _ctx; public OpenSslCipher(IntPtr algorithm, CipherMode cipherMode, int blockSizeInBytes, byte[] key, int effectiveKeyLength, byte[]? iv, bool encrypting) : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) @@ -126,6 +127,7 @@ private int CipherUpdate(byte[] input, int inputOffset, int count, byte[] output return bytesWritten; } + [MemberNotNull(nameof(_ctx))] private void OpenKey(IntPtr algorithm, byte[] key, int effectiveKeyLength) { _ctx = Interop.Crypto.EvpCipherCreate( diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Unix.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Unix.cs index f826b850ac5f1..e5c063a1124b9 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Unix.cs @@ -3,14 +3,16 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { public sealed partial class AesCcm { - private byte[] _key = null!; + private byte[] _key; + [MemberNotNull(nameof(_key))] private void ImportKey(ReadOnlySpan key) { // OpenSSL does not allow setting nonce length after setting the key diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Windows.cs index 451a80af2ec9c..52b672c986c63 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesCcm.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; using Internal.Cryptography; using Internal.NativeCrypto; @@ -10,8 +11,9 @@ namespace System.Security.Cryptography public sealed partial class AesCcm { private static readonly SafeAlgorithmHandle s_aesCcm = AesBCryptModes.OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_CCM); - private SafeKeyHandle _keyHandle = null!; // Always initialized in helper + private SafeKeyHandle _keyHandle; + [MemberNotNull(nameof(_keyHandle))] private void ImportKey(ReadOnlySpan key) { _keyHandle = Interop.BCrypt.BCryptImportKey(s_aesCcm, key); diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Unix.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Unix.cs index bf04741e86390..0bf08bac4a3de 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Unix.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Unix.cs @@ -3,14 +3,16 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { public sealed partial class AesGcm { - private SafeEvpCipherCtxHandle _ctxHandle = null!; + private SafeEvpCipherCtxHandle _ctxHandle; + [MemberNotNull(nameof(_ctxHandle))] private void ImportKey(ReadOnlySpan key) { _ctxHandle = Interop.Crypto.EvpCipherCreatePartial(GetCipher(key.Length * 8)); diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Windows.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Windows.cs index ca5b435447028..5db8df6397117 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Windows.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/AesGcm.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; using Internal.Cryptography; using Internal.NativeCrypto; @@ -10,8 +11,9 @@ namespace System.Security.Cryptography public partial class AesGcm { private static readonly SafeAlgorithmHandle s_aesGcm = AesBCryptModes.OpenAesAlgorithm(Cng.BCRYPT_CHAIN_MODE_GCM); - private SafeKeyHandle _keyHandle = null!; // Always initialized in helper + private SafeKeyHandle _keyHandle; + [MemberNotNull(nameof(_keyHandle))] private void ImportKey(ReadOnlySpan key) { _keyHandle = Interop.BCrypt.BCryptImportKey(s_aesGcm, key); diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs index 42c67d78f91b8..a46d76c12b890 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/src/System/Security/Cryptography/Rfc2898DeriveBytes.cs @@ -4,8 +4,9 @@ using System.Buffers; using System.Buffers.Binary; -using System.Text; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text; using Internal.Cryptography; @@ -21,7 +22,7 @@ public class Rfc2898DeriveBytes : DeriveBytes private HMAC _hmac; private readonly int _blockSize; - private byte[] _buffer = null!; // Initialized in helper + private byte[] _buffer; private uint _block; private int _startIndex; private int _endIndex; @@ -245,6 +246,7 @@ private HMAC OpenHmac() throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name)); } + [MemberNotNull(nameof(_buffer))] private void Initialize() { if (_buffer != null) diff --git a/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs b/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs index 19782152c0169..f06dcfd93e718 100644 --- a/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs +++ b/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs @@ -6,6 +6,7 @@ using System; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; using System.Text; @@ -290,10 +291,10 @@ public sealed class SecurityIdentifier : IdentityReference, IComparable _name; + [MemberNotNull(nameof(_name))] set { if (value == null) @@ -62,6 +64,7 @@ public string Name public string Namespace { get => _nspace; + [MemberNotNull(nameof(_nspace))] set => _nspace = value ?? throw new ArgumentNullException(nameof(Namespace)); } @@ -70,6 +73,7 @@ public string Namespace public string Pattern { get => _pattern; + [MemberNotNull(nameof(_pattern))] set => _pattern = value ?? throw new ArgumentNullException(nameof(Pattern)); } }