diff --git a/.github/workflows/codacy-analysis.yml b/.github/workflows/codacy-analysis.yml index e55d9c1a..e0d43f82 100644 --- a/.github/workflows/codacy-analysis.yml +++ b/.github/workflows/codacy-analysis.yml @@ -31,7 +31,7 @@ jobs: - name: Install latest .NET SDK uses: Elskom/setup-latest-dotnet@main with: - SDK_VERSION: '7.0.302' + SDK_VERSION: '8.0.100' RUNTIME_VERSIONS: '' - name: Restore and Build diff --git a/.github/workflows/dotnetcore-build.yml b/.github/workflows/dotnetcore-build.yml index 6627e672..445672e8 100644 --- a/.github/workflows/dotnetcore-build.yml +++ b/.github/workflows/dotnetcore-build.yml @@ -22,7 +22,7 @@ jobs: - name: Install latest .NET SDK uses: Elskom/setup-latest-dotnet@main with: - SDK_VERSION: '7.0.302' + SDK_VERSION: '8.0.100' RUNTIME_VERSIONS: '' - name: Restore, Build, and pack @@ -42,7 +42,7 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@main with: - name: Shipping + name: Shipping-${{ runner.os }} path: artifacts/packages/Release/Shipping/* - name: Upload binlog on failure. diff --git a/.github/workflows/dotnetcore-publish.yml b/.github/workflows/dotnetcore-publish.yml index 8d389884..33cd9c3d 100644 --- a/.github/workflows/dotnetcore-publish.yml +++ b/.github/workflows/dotnetcore-publish.yml @@ -26,7 +26,7 @@ jobs: - name: Install latest .NET SDK uses: Elskom/setup-latest-dotnet@main with: - SDK_VERSION: '7.0.302' + SDK_VERSION: '8.0.100' RUNTIME_VERSIONS: '' - name: Restore, Build, and pack @@ -46,7 +46,7 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@main with: - name: Shipping + name: Shipping-${{ runner.os }} path: artifacts/packages/Release/Shipping/* - name: Upload binlog on failure. diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index 14f8fb9f..6200d678 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -20,7 +20,7 @@ jobs: - name: Install latest .NET SDK uses: Elskom/setup-latest-dotnet@main with: - SDK_VERSION: '7.0.302' + SDK_VERSION: '8.0.100' RUNTIME_VERSIONS: '' - name: Restore, Build, and pack @@ -38,7 +38,7 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@main with: - name: Shipping + name: Shipping-${{ runner.os }} path: artifacts/packages/Release/Shipping/* - name: Upload binlog on failure. diff --git a/Directory.Build.props b/Directory.Build.props index c5e1266f..a5297380 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - net6.0 + net8.0 true false @@ -27,7 +27,7 @@ https://github.com/Elskom/runtime/ https://github.com/Elskom/runtime/ git - Copyright (c) 2018-2021 + Copyright (c) 2018-2023 $(CopyrightElskom) true true diff --git a/Directory.Packages.props b/Directory.Packages.props index 030fc432..87837ccc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,11 +5,11 @@ - - + + - - + + diff --git a/NuGet.config b/NuGet.config index bc5d71a4..91aeb196 100644 --- a/NuGet.config +++ b/NuGet.config @@ -5,7 +5,7 @@ - - + + diff --git a/eng/Versions.props b/eng/Versions.props index 1798ecf3..e8f6f81a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -2,7 +2,7 @@ - 6 + 8 0 0 $(MajorVersion).$(MinorVersion).$(PatchVersion) diff --git a/global.json b/global.json index 9082c72e..2b36e3c1 100644 --- a/global.json +++ b/global.json @@ -4,9 +4,9 @@ "rollForward": "latestFeature" }, "msbuild-sdks": { - "Elskom.Sdk": "6.0.4", + "Elskom.Sdk": "8.0.0", "Microsoft.Build.NoTargets": "3.7.0", - "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23316.4", - "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.23316.4" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23620.2", + "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23620.2" } } \ No newline at end of file diff --git a/ref/BlowFish/.editorconfig b/ref/BlowFish/.editorconfig index 18714482..2c9bc3f5 100644 --- a/ref/BlowFish/.editorconfig +++ b/ref/BlowFish/.editorconfig @@ -146,3 +146,6 @@ csharp_preserve_single_line_statements = true # S3903: Move '%s' into a named namespace. dotnet_diagnostic.S3903.severity = none + +# S1133: Deprecated code should be removed +dotnet_diagnostic.S1133.severity = suggestion diff --git a/ref/BlowFish/BlowFish/BlowFish.cs b/ref/BlowFish/BlowFish/BlowFish.cs index fd30697f..0501ad6b 100644 --- a/ref/BlowFish/BlowFish/BlowFish.cs +++ b/ref/BlowFish/BlowFish/BlowFish.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Blowfish encryption class. /// +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] public sealed class BlowFish : IDisposable { /// @@ -65,61 +66,33 @@ public static void XorBlock(Stream block, byte[] iv) => throw null!; /// - /// Encrypts a string in CBC mode. + /// Encrypts a string. /// - /// Plaintext data to encrypt. - /// Ciphertext with IV appended to front. - public string EncryptCBC(string pt) - => throw null!; - - /// - /// Encrypts a byte array in CBC mode. - /// IV must be created and saved manually. - /// - /// Plaintext data to encrypt. - /// Ciphertext. - public byte[] EncryptCBC(byte[] pt) - => throw null!; - - /// - /// Decrypts a string in CBC mode. - /// - /// Ciphertext with IV appended to front. - /// Plaintext. - public string DecryptCBC(string ct) - => throw null!; - - /// - /// Decrypts a byte array in CBC mode. - /// IV must be created and saved manually. - /// - /// Ciphertext data to decrypt. - /// Plaintext. - public byte[] DecryptCBC(byte[] ct) - => throw null!; - - /// - /// Encrypt a string in ECB mode. - /// - /// Plaintext to encrypt as ascii string. - /// hex value of encrypted data. - public string EncryptECB(string pt) + /// Ciphertext with IV appended to front if mode, or hex string if mode. + /// Cipher mode. + /// Ciphertext with or without the IV appended to front or if mode is not or . + [Obsolete("Using CipherMode.ECB in this method is deprecated.")] + public string? Encrypt(string ct, CipherMode mode) => throw null!; /// - /// Encrypts a byte array in ECB mode. + /// Encrypts a byte array. /// - /// Plaintext data. - /// Ciphertext bytes. - public byte[] EncryptECB(byte[] pt) + /// Ciphertext byte array. + /// Cipher mode. + /// Plaintext or if mode is not or . + [Obsolete("Using CipherMode.ECB in this method is deprecated.")] + public byte[]? Encrypt(byte[] cipherText, CipherMode mode) => throw null!; /// - /// Decrypts a string (ECB). + /// Decrypts a string. /// - /// hHex string of the ciphertext. - /// Plaintext ascii string. - public string DecryptECB(string ct) + /// Ciphertext with IV appended to front if mode, or hex string if mode. + /// Cipher mode. + /// Plaintext or if mode is not or . + [Obsolete("Using CipherMode.ECB in this method is deprecated.")] + public string? Decrypt(string ct, CipherMode mode) => throw null!; /// @@ -127,8 +100,9 @@ public string DecryptECB(string ct) /// /// Ciphertext byte array. /// Cipher mode. - /// Plaintext or if mode is not . - public byte[] Decrypt(byte[] cipherText, CipherMode mode) + /// Plaintext or if mode is not or . + [Obsolete("Using CipherMode.ECB in this method is deprecated.")] + public byte[]? Decrypt(byte[] cipherText, CipherMode mode) => throw null!; /// diff --git a/ref/BlowFish/Directory.Build.targets b/ref/BlowFish/Directory.Build.targets index bf2a2714..a199ba99 100644 --- a/ref/BlowFish/Directory.Build.targets +++ b/ref/BlowFish/Directory.Build.targets @@ -7,6 +7,7 @@ stylecop.json + diff --git a/ref/Common/Common/MessageEventArgs.cs b/ref/Common/Common/MessageEventArgs.cs index b48a47fb..0b4728f0 100644 --- a/ref/Common/Common/MessageEventArgs.cs +++ b/ref/Common/Common/MessageEventArgs.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Event that holds the message text and the caption. /// +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly.")] public class MessageEventArgs : EventArgs { /// diff --git a/ref/Common/Common/MessageEventHandler.cs b/ref/Common/Common/MessageEventHandler.cs deleted file mode 100644 index 38fdbd40..00000000 --- a/ref/Common/Common/MessageEventHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2018-2023, Els_kom org. -// https://github.com/Elskom/ -// All rights reserved. -// license: MIT, see LICENSE for more details. - -namespace Elskom.Generic.Libs; - -/// -/// Represents the method that will handle an event when the event provides data. -/// -/// -/// The source of the event. -/// -/// -/// An object that contains the event data. -/// -public delegate void MessageEventHandler(object? sender, ref MessageEventArgs e); diff --git a/ref/Common/Common/NotificationEventArgs.cs b/ref/Common/Common/NotificationEventArgs.cs index 5a334d3e..ef9f4eb8 100644 --- a/ref/Common/Common/NotificationEventArgs.cs +++ b/ref/Common/Common/NotificationEventArgs.cs @@ -8,7 +8,8 @@ namespace Elskom.Generic.Libs; /// /// Event that holds that data to call the apis for notifications. /// -public class NotificationEventArgs +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly.")] +public class NotificationEventArgs : EventArgs { /// /// Initializes a new instance of the class. diff --git a/ref/Common/Common/NotificationEventHandler.cs b/ref/Common/Common/NotificationEventHandler.cs deleted file mode 100644 index 6252cfc3..00000000 --- a/ref/Common/Common/NotificationEventHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2018-2023, Els_kom org. -// https://github.com/Elskom/ -// All rights reserved. -// license: MIT, see LICENSE for more details. - -namespace Elskom.Generic.Libs; - -/// -/// Represents the method that will handle an event when the event provides data. -/// -/// -/// The source of the event. -/// -/// -/// An object that contains the event data. -/// -public delegate void NotificationEventHandler(object? sender, ref NotificationEventArgs e); diff --git a/ref/Common/Common/ProcessStartOptions.cs b/ref/Common/Common/ProcessStartOptions.cs index 93a1a792..c8775cd0 100644 --- a/ref/Common/Common/ProcessStartOptions.cs +++ b/ref/Common/Common/ProcessStartOptions.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Creates a Process with additional options. /// +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly.")] public sealed class ProcessStartOptions { /// diff --git a/ref/Common/Directory.Build.targets b/ref/Common/Directory.Build.targets index b77deb3c..fa5da6f7 100644 --- a/ref/Common/Directory.Build.targets +++ b/ref/Common/Directory.Build.targets @@ -5,6 +5,7 @@ stylecop.json + diff --git a/ref/GenericPluginLoader/Directory.Build.targets b/ref/GenericPluginLoader/Directory.Build.targets index daf30b81..08f189a5 100644 --- a/ref/GenericPluginLoader/Directory.Build.targets +++ b/ref/GenericPluginLoader/Directory.Build.targets @@ -10,6 +10,7 @@ + diff --git a/ref/GenericPluginLoader/GenericPluginLoader/GenericPluginLoader.cs b/ref/GenericPluginLoader/GenericPluginLoader/GenericPluginLoader.cs index 404533af..91cc3244 100644 --- a/ref/GenericPluginLoader/GenericPluginLoader/GenericPluginLoader.cs +++ b/ref/GenericPluginLoader/GenericPluginLoader/GenericPluginLoader.cs @@ -13,12 +13,13 @@ namespace Elskom.Generic.Libs; /// /// A generic loader for plugins. /// +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] public sealed class GenericPluginLoader { /// /// Triggers when the Plugin Loader has a message to send to the application. /// - public static event MessageEventHandler? PluginLoaderMessage + public static event EventHandler? PluginLoaderMessage { add => throw null!; remove => throw null!; diff --git a/ref/GitInformation/GitInformation.cs b/ref/GitInformation/GitInformation.cs index e693fedc..14a5b4bd 100644 --- a/ref/GitInformation/GitInformation.cs +++ b/ref/GitInformation/GitInformation.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Obtain the git repository information for the assembly. /// +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] public class GitInformation { /// diff --git a/ref/GitInformation/GitInformationAttribute.cs b/ref/GitInformation/GitInformationAttribute.cs index c3739e93..ff9081f3 100644 --- a/ref/GitInformation/GitInformationAttribute.cs +++ b/ref/GitInformation/GitInformationAttribute.cs @@ -11,7 +11,7 @@ namespace Elskom.Generic.Libs; /// Attribute that creates and registers an instance of the class for the assembly. /// [AttributeUsage(AttributeTargets.Assembly, Inherited = false)] -public class GitInformationAttribute : Attribute +public sealed class GitInformationAttribute : Attribute { /// /// Initializes a new instance of the class. @@ -31,6 +31,7 @@ public class GitInformationAttribute : Attribute /// /// Thrown when is . /// + [SuppressMessage("Design", "CA1019:Define accessors for attribute arguments", Justification = "Do not want the values of the mandatory arguments to be retrievable.")] public GitInformationAttribute(string headdesc, string commit, string branchname, Type assemblyType) => throw null!; } diff --git a/ref/MessageManager/MessageManager/MessageManager.cs b/ref/MessageManager/MessageManager/MessageManager.cs index cdd5e39b..7305c9d2 100644 --- a/ref/MessageManager/MessageManager/MessageManager.cs +++ b/ref/MessageManager/MessageManager/MessageManager.cs @@ -13,7 +13,7 @@ public static class MessageManager /// /// Occurs when the ShowError(), ShowInfo(), or ShowWarning() methods is told to use Notifications. /// - public static event NotificationEventHandler? Notification + public static event EventHandler? Notification { add => throw null!; remove => throw null!; diff --git a/ref/MiniDump/Directory.Build.targets b/ref/MiniDump/Directory.Build.targets index eb3b99d8..7585d979 100644 --- a/ref/MiniDump/Directory.Build.targets +++ b/ref/MiniDump/Directory.Build.targets @@ -8,6 +8,7 @@ stylecop.json + diff --git a/ref/MiniDump/MiniDump/MiniDumpAttribute.cs b/ref/MiniDump/MiniDump/MiniDumpAttribute.cs index 7bb261cc..33776593 100644 --- a/ref/MiniDump/MiniDump/MiniDumpAttribute.cs +++ b/ref/MiniDump/MiniDump/MiniDumpAttribute.cs @@ -18,6 +18,7 @@ namespace Elskom.Generic.Libs; /// targeting Windows Forms to bring thread exception support and making build harder to maintain. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly | AttributeTargets.Method)] +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] public sealed class MiniDumpAttribute : Attribute { /// @@ -56,7 +57,7 @@ public MiniDumpAttribute() /// } /// /// - public static event MiniDumpEventHandler? Dump + public static event EventHandler? Dump { add => throw null!; remove => throw null!; @@ -65,7 +66,7 @@ public static event MiniDumpEventHandler? Dump /// /// Occurs when a mini-dump is generated or fails. /// - public static event MessageEventHandler? DumpMessage + public static event EventHandler? DumpMessage { add => throw null!; remove => throw null!; diff --git a/ref/MiniDump/MiniDump/MiniDumpEventArgs.cs b/ref/MiniDump/MiniDump/MiniDumpEventArgs.cs index 8971c9db..3b9fa6f8 100644 --- a/ref/MiniDump/MiniDump/MiniDumpEventArgs.cs +++ b/ref/MiniDump/MiniDump/MiniDumpEventArgs.cs @@ -8,7 +8,8 @@ namespace Elskom.Generic.Libs; /// /// Event that holds the information needed to create a dump. /// -public class MiniDumpEventArgs +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] +public class MiniDumpEventArgs : EventArgs { /// /// Gets the process id of the current process that the dump is to be made on. diff --git a/ref/MiniDump/MiniDump/MiniDumpEventHandler.cs b/ref/MiniDump/MiniDump/MiniDumpEventHandler.cs deleted file mode 100644 index b2e1353f..00000000 --- a/ref/MiniDump/MiniDump/MiniDumpEventHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2018-2023, Els_kom org. -// https://github.com/Elskom/ -// All rights reserved. -// license: MIT, see LICENSE for more details. - -namespace Elskom.Generic.Libs; - -/// -/// Represents the method that will handle an event when the event provides data. -/// -/// -/// The source of the event. -/// -/// -/// An object that contains the event data. -/// -public delegate void MiniDumpEventHandler(object? sender, ref MiniDumpEventArgs e); diff --git a/ref/MiniDump/MiniDump/MiniDumpType.cs b/ref/MiniDump/MiniDump/MiniDumpType.cs index 277b7733..f159f16f 100644 --- a/ref/MiniDump/MiniDump/MiniDumpType.cs +++ b/ref/MiniDump/MiniDump/MiniDumpType.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Represents the type of dump that can be requested. /// +[SuppressMessage("Design", "CA1008:Enums should have zero value", Justification = "Controls MiniDump Types.")] public enum MiniDumpType { /// diff --git a/ref/PluginFramework/Directory.Build.targets b/ref/PluginFramework/Directory.Build.targets index faea8a9b..6136f172 100644 --- a/ref/PluginFramework/Directory.Build.targets +++ b/ref/PluginFramework/Directory.Build.targets @@ -8,6 +8,7 @@ stylecop.json + diff --git a/ref/PluginFramework/PluginFramework/EntryVer.cs b/ref/PluginFramework/PluginFramework/EntryVer.cs index 7178d5ae..9a2e3cd8 100644 --- a/ref/PluginFramework/PluginFramework/EntryVer.cs +++ b/ref/PluginFramework/PluginFramework/EntryVer.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// This Class holds all the KOM entry Information. /// +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] public class EntryVer { /// diff --git a/ref/PluginFramework/PluginFramework/KOMManager.cs b/ref/PluginFramework/PluginFramework/KOMManager.cs index 96b89957..a040e38b 100644 --- a/ref/PluginFramework/PluginFramework/KOMManager.cs +++ b/ref/PluginFramework/PluginFramework/KOMManager.cs @@ -13,7 +13,7 @@ public static class KOMManager /// /// The event to which allows getting the message to do stuff with. /// - public static event MessageEventHandler? MessageEvent + public static event EventHandler? MessageEvent { add => throw null!; remove => throw null!; @@ -39,7 +39,7 @@ public static bool UnpackingState /// /// The list of plugins. /// - public static List Komplugins + public static IList Komplugins => throw null!; /// @@ -48,7 +48,7 @@ public static List Komplugins /// /// The list of plugins. /// - public static List Encryptionplugins + public static IList Encryptionplugins => throw null!; /// @@ -57,7 +57,7 @@ public static List Encryptionplugins /// /// The list of plugins. /// - public static List Callbackplugins + public static IList Callbackplugins => throw null!; /// diff --git a/ref/PluginUpdateCheck/.editorconfig b/ref/PluginUpdateCheck/.editorconfig index 27d02fe1..77fcd032 100644 --- a/ref/PluginUpdateCheck/.editorconfig +++ b/ref/PluginUpdateCheck/.editorconfig @@ -153,5 +153,8 @@ dotnet_diagnostic.CA1303.severity = warning # CA1305: Specify IFormatProvider dotnet_diagnostic.CA1305.severity = warning +# CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1591.severity = suggestion + # S3903: Move '%s' into a named namespace. dotnet_diagnostic.S3903.severity = none diff --git a/ref/PluginUpdateCheck/Directory.Build.targets b/ref/PluginUpdateCheck/Directory.Build.targets index 39c8f246..6e64d275 100644 --- a/ref/PluginUpdateCheck/Directory.Build.targets +++ b/ref/PluginUpdateCheck/Directory.Build.targets @@ -7,6 +7,7 @@ stylecop.json + diff --git a/ref/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateCheck.cs b/ref/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateCheck.cs index 3171dbda..60cdb31a 100644 --- a/ref/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateCheck.cs +++ b/ref/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateCheck.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// A generic plugin update checker. /// +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] public sealed class PluginUpdateCheck : IDisposable { /// @@ -20,7 +21,7 @@ public PluginUpdateCheck(IServiceProvider serviceprovider) /// /// Event that fires when a new message should show up. /// - public static event MessageEventHandler? MessageEvent + public static event EventHandler? MessageEvent { add => throw null!; remove => throw null!; @@ -29,7 +30,7 @@ public static event MessageEventHandler? MessageEvent /// /// Gets the plugin urls used in all instances. /// - public List? PluginUrls + public IList? PluginUrls => throw null!; /// @@ -41,7 +42,7 @@ public bool ShowMessage /// /// Gets a list of instances representing the plugins that needs updating or are to be installed. /// - public List PluginUpdateDatas + public IList PluginUpdateDatas => throw null!; /// @@ -52,7 +53,7 @@ public List PluginUpdateDatas /// Thrown if or are . /// A value indicating if the operation was successful or not. // catches the plugin urls and uses that cache to detect added urls, and only appends those to the list. - public bool CheckForUpdates(string[] pluginURLs, List pluginTypes) + public bool CheckForUpdates(string[] pluginURLs, IList pluginTypes) => throw null!; /// diff --git a/ref/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateData.cs b/ref/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateData.cs index eb74798c..fa612277 100644 --- a/ref/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateData.cs +++ b/ref/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateData.cs @@ -8,7 +8,8 @@ namespace Elskom.Generic.Libs; /// /// The Plugin Update data for a plugin. /// -public struct PluginUpdateData +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] +public struct PluginUpdateData : IEquatable { /// /// Gets the plugin name this instance is pointing to. @@ -37,6 +38,24 @@ public Uri DownloadUrl /// /// Gets the files to the plugin to download. /// - public List DownloadFiles + public IList DownloadFiles + => throw null!; + + public static bool operator ==(PluginUpdateData left, PluginUpdateData right) + => throw null!; + + public static bool operator !=(PluginUpdateData left, PluginUpdateData right) + => throw null!; + + /// + public override readonly bool Equals(object? obj) + => throw null!; + + /// + public readonly bool Equals(PluginUpdateData other) + => throw null!; + + /// + public override readonly int GetHashCode() => throw null!; } diff --git a/ref/SettingsFile/Directory.Build.targets b/ref/SettingsFile/Directory.Build.targets index fece2881..deb7c236 100644 --- a/ref/SettingsFile/Directory.Build.targets +++ b/ref/SettingsFile/Directory.Build.targets @@ -8,6 +8,7 @@ stylecop.json + diff --git a/ref/SettingsFile/SettingsFile/JsonSettings.cs b/ref/SettingsFile/SettingsFile/JsonSettings.cs index b8e3e26e..66461036 100644 --- a/ref/SettingsFile/SettingsFile/JsonSettings.cs +++ b/ref/SettingsFile/SettingsFile/JsonSettings.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Json Setting file data. /// +[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Ref assembly which must match ABI of runtime.")] public class JsonSettings { /// @@ -84,6 +85,7 @@ public int UseNotifications /// Gets or sets the sources to use to install plugins from. /// [JsonPropertyName(nameof(Sources))] + [SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "Needed for settings json file.")] public string[] Sources { get => throw null!; diff --git a/ref/ZipAssembly/.editorconfig b/ref/ZipAssembly/.editorconfig index a01d0fb9..877dbcf8 100644 --- a/ref/ZipAssembly/.editorconfig +++ b/ref/ZipAssembly/.editorconfig @@ -152,3 +152,6 @@ dotnet_diagnostic.S3925.severity = none # S3903: Move '%s' into a named namespace. dotnet_diagnostic.S3903.severity = none + +# S1133: Do not forget to remove this deprecated code someday. +dotnet_diagnostic.S1133.severity = suggestion diff --git a/ref/ZipAssembly/Directory.Build.targets b/ref/ZipAssembly/Directory.Build.targets index 3d6c019d..c9caa624 100644 --- a/ref/ZipAssembly/Directory.Build.targets +++ b/ref/ZipAssembly/Directory.Build.targets @@ -6,6 +6,7 @@ stylecop.json + diff --git a/ref/ZipAssembly/ZipAssembly/ZipAssemblyLoadException.cs b/ref/ZipAssembly/ZipAssembly/ZipAssemblyLoadException.cs index 14998ddc..23ba808a 100644 --- a/ref/ZipAssembly/ZipAssembly/ZipAssemblyLoadException.cs +++ b/ref/ZipAssembly/ZipAssembly/ZipAssemblyLoadException.cs @@ -62,6 +62,8 @@ public ZipAssemblyLoadException(string message, Exception innerException) /// /// The class name is or is zero (0). /// + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] protected ZipAssemblyLoadException(SerializationInfo info, StreamingContext context) : base(info, context) => throw null!; diff --git a/src/BlowFish/.editorconfig b/src/BlowFish/.editorconfig index 18714482..9251a1a1 100644 --- a/src/BlowFish/.editorconfig +++ b/src/BlowFish/.editorconfig @@ -146,3 +146,6 @@ csharp_preserve_single_line_statements = true # S3903: Move '%s' into a named namespace. dotnet_diagnostic.S3903.severity = none + +# S1133: Do not forget to remove this deprecated code someday. +dotnet_diagnostic.S1133.severity = suggestion diff --git a/src/BlowFish/BlowFish/BlowFish.cs b/src/BlowFish/BlowFish/BlowFish.cs index 28db06a5..067c25c9 100644 --- a/src/BlowFish/BlowFish/BlowFish.cs +++ b/src/BlowFish/BlowFish/BlowFish.cs @@ -12,46 +12,21 @@ namespace Elskom.Generic.Libs; public sealed partial class BlowFish { [DisposeField(false)] - private RandomNumberGenerator randomSource = RandomNumberGenerator.Create(); - - // SBLOCKS - [NullOnDispose] - private uint[] bfS0 = null!; - [NullOnDispose] - private uint[] bfS1 = null!; - [NullOnDispose] - private uint[] bfS2 = null!; - [NullOnDispose] - private uint[] bfS3 = null!; - [NullOnDispose] - private uint[] bfP = null!; - - // HALF-BLOCKS - private uint xlPar; - private uint xrPar; - [NullOnDispose] - private byte[] initVector = null!; - private bool iVSet; + private BlowFishInternal bfInternal; /// /// Initializes a new instance of the class with the hex key provided. /// /// Cipher key as a hex string. public BlowFish(string hexKey) - { - ArgumentNullException.ThrowIfNull(hexKey); - this.SetupKey(HexToByte(hexKey.AsSpan())); - } + => this.bfInternal = new(hexKey); /// /// Initializes a new instance of the class with the byte key provided. /// /// Cipher key as a byte array. public BlowFish(byte[] cipherKey) - { - ArgumentNullException.ThrowIfNull(cipherKey); - this.SetupKey(cipherKey); - } + => this.bfInternal = new(cipherKey); /// /// Gets or sets initialization vector for CBC mode. @@ -61,13 +36,8 @@ public BlowFish(byte[] cipherKey) /// public IEnumerable IV { - get => this.initVector; - set - { - ThrowHelpers.ThrowInvalidOperation(value.ToArray().Length != 8, Resources.BlowFish_Invalid_IV_Size!); - this.initVector = value.ToArray(); - this.iVSet = true; - } + get => this.bfInternal.IV; + set => this.bfInternal.IV = value; } /// @@ -76,209 +46,11 @@ public IEnumerable IV /// /// A value indicating whether non standard blowfish mode. /// - public bool NonStandard { get; set; } - - // SBLOCKS ARE THE HEX DIGITS OF PI. - // The amount of hex digits can be increased if you want to experiment with more rounds and longer key lengths - private static ReadOnlySpan SetupP - => new uint[] - { - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, - 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b, - }; - - private static ReadOnlySpan SetupS0 - => new uint[] - { - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, - 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, - 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, - 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, - 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, - 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, - 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, - 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, - 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, - 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, - 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, - 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, - 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, - 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, - 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, - 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, - 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, - 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, - 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, - 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, - 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, - 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, - }; - - private static ReadOnlySpan SetupS1 - => new uint[] - { - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, - 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, - 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, - 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, - 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, - 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, - 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, - 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, - 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, - 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, - 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, - 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, - 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, - 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, - 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, - 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, - 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, - 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, - 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, - 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, - 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, - 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, - }; - - private static ReadOnlySpan SetupS2 - => new uint[] - { - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, - 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, - 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, - 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, - 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, - 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, - 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, - 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, - 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, - 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, - 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, - 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, - 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, - 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, - 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, - 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, - 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, - 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, - 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, - 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, - 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, - 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, - }; - - private static ReadOnlySpan SetupS3 - => new uint[] - { - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, - 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, - 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, - 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, - 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, - 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, - 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, - 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, - 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, - 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, - 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, - 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, - 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, - 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, - 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, - 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, - 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, - 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, - 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, - 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, - 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, - 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, - }; + public bool NonStandard + { + get => this.bfInternal.NonStandard; + set => this.bfInternal.NonStandard = value; + } /// /// XoR encrypts two 8 bit blocks. @@ -287,8 +59,10 @@ private static ReadOnlySpan SetupS3 /// 8 bit block 2. public static void XorBlock(ref byte[] block, byte[] iv) { - ThrowHelpers.ThrowArgumentOutOfRange(block.Length is 0, nameof(block)); - ThrowHelpers.ThrowArgumentOutOfRange(iv.Length is 0, nameof(iv)); + ArgumentNullException.ThrowIfNull(block); + ArgumentNullException.ThrowIfNull(iv); + ArgumentOutOfRangeException.ThrowIfEqual(block.Length, 0); + ArgumentOutOfRangeException.ThrowIfEqual(iv.Length, 0); for (var i = 0; i < block.Length; i++) { block[i] ^= iv[i % iv.Length]; @@ -311,97 +85,67 @@ public static void XorBlock(Stream block, byte[] iv) } /// - /// Encrypts a string in CBC mode. + /// Encrypts a string. /// - /// Plaintext data to encrypt. - /// Ciphertext with IV appended to front. - public string EncryptCBC(string pt) - { - if (!this.iVSet) - { - _ = this.SetRandomIV(); - } - - return $"{ByteToHex(this.initVector)}{ByteToHex(this.EncryptCBC(Encoding.ASCII.GetBytes(pt)))}"; - } - - /// - /// Encrypts a byte array in CBC mode. - /// IV must be created and saved manually. - /// - /// Plaintext data to encrypt. - /// Ciphertext. - public byte[] EncryptCBC(byte[] pt) - { - ArgumentNullException.ThrowIfNull(pt); - return this.Crypt_CBC((byte[])pt.Clone(), false); - } - - /// - /// Decrypts a string in CBC mode. - /// - /// Ciphertext with IV appended to front. - /// Plaintext. - public string DecryptCBC(string ct) - { - ArgumentNullException.ThrowIfNull(ct); - this.IV = HexToByte(ct.AsSpan().Slice(0, 16)); - return Encoding.ASCII.GetString(this.DecryptCBC(HexToByte(ct.AsSpan().Slice(16))).Remove((byte)'\0')); - } - - /// - /// Decrypts a byte array in CBC mode. - /// IV must be created and saved manually. - /// - /// Ciphertext data to decrypt. - /// Plaintext. - public byte[] DecryptCBC(byte[] ct) - { - ArgumentNullException.ThrowIfNull(ct); - return this.Crypt_CBC((byte[])ct.Clone(), true); - } - - /// - /// Encrypt a string in ECB mode. - /// - /// Plaintext to encrypt as ascii string. - /// hex value of encrypted data. - public string EncryptECB(string pt) - => ByteToHex(this.EncryptECB(Encoding.ASCII.GetBytes(pt))); + /// Ciphertext with IV appended to front if mode, or hex string if mode. + /// Cipher mode. + /// Ciphertext with or without the IV appended to front or if mode is not or . + [SuppressMessage("Security", "CA5358:Review cipher mode usage with cryptography experts", Justification = "Part of ABI.")] + [Obsolete("Using CipherMode.ECB in this method is deprecated.")] + public string? Encrypt(string ct, CipherMode mode) + => mode switch + { + CipherMode.ECB => this.bfInternal.EncryptECB(ct), + CipherMode.CBC => this.bfInternal.EncryptCBC(ct), + _ => null, + }; /// - /// Encrypts a byte array in ECB mode. + /// Encrypts a byte array. /// - /// Plaintext data. - /// Ciphertext bytes. - public byte[] EncryptECB(byte[] pt) - { - ArgumentNullException.ThrowIfNull(pt); - return this.Crypt_ECB((byte[])pt.Clone(), false); - } + /// Ciphertext byte array. + /// Cipher mode. + /// Plaintext or if mode is not or . + [SuppressMessage("Security", "CA5358:Review cipher mode usage with cryptography experts", Justification = "Part of ABI.")] + [Obsolete("Using CipherMode.ECB in this method is deprecated.")] + public byte[]? Encrypt(byte[] cipherText, CipherMode mode) + => mode switch + { + CipherMode.ECB => this.bfInternal.EncryptECB(cipherText), + CipherMode.CBC => this.bfInternal.EncryptCBC(cipherText), + _ => null, + }; /// - /// Decrypts a string (ECB). + /// Decrypts a string. /// - /// hHex string of the ciphertext. - /// Plaintext ascii string. - public string DecryptECB(string ct) - { - ArgumentNullException.ThrowIfNull(ct); - return Encoding.ASCII.GetString(this.Decrypt_ECB(HexToByte(ct.AsSpan())).Remove((byte)'\0')); - } + /// Ciphertext with IV appended to front if mode, or hex string if mode. + /// Cipher mode. + /// Plaintext or if mode is not or . + [SuppressMessage("Security", "CA5358:Review cipher mode usage with cryptography experts", Justification = "Part of ABI.")] + [Obsolete("Using CipherMode.ECB in this method is deprecated.")] + public string? Decrypt(string ct, CipherMode mode) + => mode switch + { + CipherMode.ECB => this.bfInternal.DecryptECB(ct), + CipherMode.CBC => this.bfInternal.DecryptCBC(ct), + _ => null, + }; /// /// Decrypts a byte array. /// /// Ciphertext byte array. /// Cipher mode. - /// Plaintext or if mode is not . + /// Plaintext or if mode is not or . + [SuppressMessage("Security", "CA5358:Review cipher mode usage with cryptography experts", Justification = "Part of ABI.")] + [Obsolete("Using CipherMode.ECB in this method is deprecated.")] public byte[]? Decrypt(byte[] cipherText, CipherMode mode) => mode switch { - CipherMode.ECB => this.Decrypt_ECB(cipherText), - CipherMode.CBC or CipherMode.CFB or CipherMode.CTS or CipherMode.OFB or _ => null, + CipherMode.ECB => this.bfInternal.DecryptECB(cipherText), + CipherMode.CBC => this.bfInternal.DecryptCBC(cipherText), + _ => null, }; /// @@ -409,283 +153,5 @@ public string DecryptECB(string ct) /// /// The random IV. public byte[] SetRandomIV() - { - Span iv = stackalloc byte[8]; - this.randomSource.GetBytes(iv); - this.initVector = iv.ToArray(); - this.iVSet = true; - return this.initVector; - } - - // gets the first byte in a uint - private static byte WordByte0(uint w) - => WordByte3(w / 256 / 256 / 256); - - // gets the second byte in a uint - private static byte WordByte1(uint w) - => WordByte3(w / 256 / 256); - - // gets the third byte in a uint - private static byte WordByte2(uint w) - => WordByte3(w / 256); - - // gets the fourth byte in a uint - private static byte WordByte3(uint w) - => (byte)(w % 256); - - // converts a byte array to a hex string - private static string ByteToHex(byte[] bytes) - { - StringBuilder s = new(); - foreach (var b in bytes) - { - _ = s.Append(b.ToString("x2", CultureInfo.InvariantCulture)); - } - - return s.ToString(); - } - - // converts a hex string to a byte array - private static byte[] HexToByte(ReadOnlySpan hex) - { - Span r = stackalloc byte[hex.Length / 2]; - for (var i = 0; i < hex.Length - 1; i += 2) - { - var a = GetHex(hex[i]); - var b = GetHex(hex[i + 1]); - r[i / 2] = (byte)((a * 16) + b); - } - - return r.ToArray(); - } - - // converts a single hex character to it's decimal value - private static byte GetHex(char x) - => x switch - { - <= '9' and >= '0' => (byte)(x - '0'), - <= 'z' and >= 'a' => (byte)(x - 'a' + 10), - <= 'Z' and >= 'A' => (byte)(x - 'A' + 10), - _ => 0, - }; - - private byte[] Decrypt_ECB(byte[] ct) - => this.Crypt_ECB(ct, true); - - private void SetupKey(Span cipherKey) - { - this.bfP = SetupP.ToArray(); - - // set up the S blocks - this.bfS0 = SetupS0.ToArray(); - this.bfS1 = SetupS1.ToArray(); - this.bfS2 = SetupS2.ToArray(); - this.bfS3 = SetupS3.ToArray(); - ThrowHelpers.ThrowInvalidOperation(cipherKey.Length > 56, Resources.BlowFish_Key_Too_Long!); - var j = 0; - for (var i = 0; i < 18; i++) - { - var d = (uint)((((((cipherKey[j % cipherKey.Length] * 256) + cipherKey[(j + 1) % cipherKey.Length]) * 256) + cipherKey[(j + 2) % cipherKey.Length]) * 256) + cipherKey[(j + 3) % cipherKey.Length]); - this.bfP[i] ^= d; - j = (j + 4) % cipherKey.Length; - } - - this.xlPar = 0; - this.xrPar = 0; - for (var i = 0; i < 18; i += 2) - { - this.Encipher(); - this.bfP[i] = this.xlPar; - this.bfP[i + 1] = this.xrPar; - } - - for (var i = 0; i < 256; i += 2) - { - this.Encipher(); - this.bfS0[i] = this.xlPar; - this.bfS0[i + 1] = this.xrPar; - } - - for (var i = 0; i < 256; i += 2) - { - this.Encipher(); - this.bfS1[i] = this.xlPar; - this.bfS1[i + 1] = this.xrPar; - } - - for (var i = 0; i < 256; i += 2) - { - this.Encipher(); - this.bfS2[i] = this.xlPar; - this.bfS2[i + 1] = this.xrPar; - } - - for (var i = 0; i < 256; i += 2) - { - this.Encipher(); - this.bfS3[i] = this.xlPar; - this.bfS3[i + 1] = this.xrPar; - } - } - - private byte[] Crypt_ECB(byte[] text, bool decrypt) - { - var paddedLen = text.Length % 8 == 0 ? text.Length : text.Length + 8 - (text.Length % 8); - if (paddedLen != text.Length) - { - Array.Resize(ref text, paddedLen); - } - - var plainText = text.AsSpan(); - for (var i = 0; i < plainText.Length; i += 8) - { - var block = plainText.Slice(i, 8); - if (decrypt) - { - this.BlockDecrypt(block); - } - else - { - this.BlockEncrypt(block); - } - } - - return text; - } - - private byte[] Crypt_CBC(byte[] text, bool decrypt) - { - ThrowHelpers.ThrowInvalidOperation(!this.iVSet, Resources.BlowFish_IV_Not_Set!); - var paddedLen = text.Length % 8 == 0 ? text.Length : text.Length + 8 - (text.Length % 8); - if (paddedLen != text.Length) - { - Array.Resize(ref text, paddedLen); - } - - var plainText = text.AsSpan(); - byte[]? preblock = null; - var iv = this.initVector.AsSpan().Slice(0, 8); - for (var i = 0; i < plainText.Length; i += 8) - { - var block = plainText.Slice(i, 8); - if (decrypt) - { - preblock = block.ToArray(); - this.BlockDecrypt(block); - } - - for (var v = 0; v < block.Length; v++) - { - block[v] ^= iv[v % iv.Length]; - } - - if (!decrypt) - { - this.BlockEncrypt(block); - iv = block; - } - else - { - // clone preblock into iv. - iv = preblock.AsSpan(); - } - } - - return text; - } - - private void BlockEncrypt(Span block) - { - this.SetBlock(block); - this.Encipher(); - this.GetBlock(block); - } - - private void BlockDecrypt(Span block) - { - this.SetBlock(block); - this.Decipher(); - this.GetBlock(block); - } - - private void SetBlock(Span block) - { - // split the block - if (!this.NonStandard) - { - // ToUInt32 requires the bytes in reverse order - block.Reverse(); - } - - this.xrPar = BitConverter.ToUInt32(block.ToArray(), 0); - this.xlPar = BitConverter.ToUInt32(block.ToArray(), 4); - if (!this.NonStandard) - { - // reverse them back. - block.Reverse(); - } - } - - private void GetBlock(Span block) - { - byte[] block1; - byte[] block2; - if (this.NonStandard) - { - block1 = BitConverter.GetBytes(this.xrPar); - block2 = BitConverter.GetBytes(this.xlPar); - } - else - { - block1 = BitConverter.GetBytes(this.xlPar); - block2 = BitConverter.GetBytes(this.xrPar); - - // GetBytes returns the bytes in reverse order - Array.Reverse(block1); - Array.Reverse(block2); - } - - // join the block - Array.Resize(ref block1, block1.Length + 4); - block2.CopyTo(block1, 4); - block1.CopyTo(block); - } - - private void Encipher() - { - this.xlPar ^= this.bfP[0]; - for (uint i = 0; i < 16; i += 2) - { - this.xrPar = this.Round(this.xrPar, this.xlPar, i + 1); - this.xlPar = this.Round(this.xlPar, this.xrPar, i + 2); - } - - this.xrPar ^= this.bfP[17]; - - // swap the blocks - (this.xlPar, this.xrPar) = (this.xrPar, this.xlPar); - } - - private void Decipher() - { - this.xlPar ^= this.bfP[17]; - for (uint i = 16; i > 0; i -= 2) - { - this.xrPar = this.Round(this.xrPar, this.xlPar, i); - this.xlPar = this.Round(this.xlPar, this.xrPar, i - 1); - } - - this.xrPar ^= this.bfP[0]; - - // swap the blocks - (this.xlPar, this.xrPar) = (this.xrPar, this.xlPar); - } - - private uint Round(uint a, uint b, uint n) - { - var x1 = (this.bfS0[WordByte0(b)] + this.bfS1[WordByte1(b)]) ^ this.bfS2[WordByte2(b)]; - var x2 = x1 + this.bfS3[WordByte3(b)]; - var x3 = x2 ^ this.bfP[n]; - return x3 ^ a; - } + => this.bfInternal.SetRandomIV(); } diff --git a/src/BlowFish/BlowFish/BlowFishInternal.cs b/src/BlowFish/BlowFish/BlowFishInternal.cs new file mode 100644 index 00000000..6c34c927 --- /dev/null +++ b/src/BlowFish/BlowFish/BlowFishInternal.cs @@ -0,0 +1,621 @@ +// Copyright (c) 2018-2023, Els_kom org. +// https://github.com/Elskom/ +// All rights reserved. +// license: MIT, see LICENSE for more details. + +namespace Elskom.Generic.Libs; + +/// +/// Blowfish encryption class. +/// +[GenerateDispose(false)] +internal sealed partial class BlowFishInternal +{ + [DisposeField(false)] + private RandomNumberGenerator randomSource = RandomNumberGenerator.Create(); + + // SBLOCKS + [NullOnDispose] + private uint[] bfS0 = null!; + [NullOnDispose] + private uint[] bfS1 = null!; + [NullOnDispose] + private uint[] bfS2 = null!; + [NullOnDispose] + private uint[] bfS3 = null!; + [NullOnDispose] + private uint[] bfP = null!; + + // HALF-BLOCKS + private uint xlPar; + private uint xrPar; + [NullOnDispose] + private byte[] initVector = null!; + private bool iVSet; + + /// + /// Initializes a new instance of the class with the hex key provided. + /// + /// Cipher key as a hex string. + public BlowFishInternal(string hexKey) + { + ArgumentNullException.ThrowIfNull(hexKey); + this.SetupKey(HexToByte(hexKey.AsSpan())); + } + + /// + /// Initializes a new instance of the class with the byte key provided. + /// + /// Cipher key as a byte array. + public BlowFishInternal(byte[] cipherKey) + { + ArgumentNullException.ThrowIfNull(cipherKey); + this.SetupKey(cipherKey); + } + + internal IEnumerable IV + { + get => this.initVector; + set + { + var array = value?.ToArray() ?? Array.Empty(); + ThrowHelpers.ThrowInvalidOperation(array!.Length != 8, Resources.BlowFish_Invalid_IV_Size!); + this.initVector = array; + this.iVSet = true; + } + } + + internal bool NonStandard { get; set; } + + // SBLOCKS ARE THE HEX DIGITS OF PI. + // The amount of hex digits can be increased if you want to experiment with more rounds and longer key lengths + private static ReadOnlySpan SetupP + => new uint[] + { + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, + 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b, + }; + + private static ReadOnlySpan SetupS0 + => new uint[] + { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, + 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, + 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, + 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, + 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, + 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, + 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, + 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, + 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, + 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, + 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, + 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, + 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, + 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, + 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, + 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, + 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, + 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, + 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, + 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, + 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, + 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, + }; + + private static ReadOnlySpan SetupS1 + => new uint[] + { + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, + 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, + 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, + 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, + 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, + 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, + 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, + 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, + 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, + 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, + 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, + 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, + 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, + 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, + 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, + 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, + 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, + 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, + 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, + 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, + 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, + 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, + }; + + private static ReadOnlySpan SetupS2 + => new uint[] + { + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, + 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, + 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, + 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, + 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, + 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, + 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, + 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, + 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, + 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, + 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, + 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, + 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, + 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, + 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, + 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, + 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, + 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, + 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, + 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, + 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, + 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, + }; + + private static ReadOnlySpan SetupS3 + => new uint[] + { + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, + 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, + 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, + 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, + 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, + 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, + 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, + 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, + 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, + 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, + 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, + 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, + 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, + 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, + 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, + 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, + 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, + 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, + 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, + 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, + 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, + 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, + }; + + internal string EncryptCBC(string pt) + { + if (!this.iVSet) + { + _ = this.SetRandomIV(); + } + + return $"{ByteToHex(this.initVector)}{ByteToHex(this.EncryptCBC(Encoding.ASCII.GetBytes(pt)))}"; + } + + internal byte[] EncryptCBC(byte[] pt) + { + ArgumentNullException.ThrowIfNull(pt); + return this.Crypt_CBC((byte[])pt.Clone(), false); + } + + internal string DecryptCBC(string ct) + { + ArgumentNullException.ThrowIfNull(ct); + this.IV = HexToByte(ct.AsSpan().Slice(0, 16)); + return Encoding.ASCII.GetString(this.DecryptCBC(HexToByte(ct.AsSpan().Slice(16))).Remove((byte)'\0')); + } + + internal byte[] DecryptCBC(byte[] ct) + { + ArgumentNullException.ThrowIfNull(ct); + return this.Crypt_CBC((byte[])ct.Clone(), true); + } + + [Obsolete("Use CBC version.")] + internal string EncryptECB(string pt) + => ByteToHex(this.EncryptECB(Encoding.ASCII.GetBytes(pt))); + + [Obsolete("Use CBC version.")] + internal byte[] EncryptECB(byte[] pt) + { + ArgumentNullException.ThrowIfNull(pt); + return this.Crypt_ECB((byte[])pt.Clone(), false); + } + + [Obsolete("Use CBC version.")] + internal string DecryptECB(string ct) + { + ArgumentNullException.ThrowIfNull(ct); + return Encoding.ASCII.GetString(this.Decrypt_ECB(HexToByte(ct.AsSpan())).Remove((byte)'\0')); + } + + [Obsolete("Use CBC version.")] + internal byte[] DecryptECB(byte[] ct) + { + ArgumentNullException.ThrowIfNull(ct); + return this.Decrypt_ECB(HexToByte(ct.AsSpan())).Remove((byte)'\0'); + } + + [Obsolete("Use CBC version.")] + internal byte[] Decrypt_ECB(byte[] ct) + => this.Crypt_ECB(ct, true); + + internal byte[] SetRandomIV() + { + Span iv = stackalloc byte[8]; + this.randomSource.GetBytes(iv); + this.initVector = iv.ToArray(); + this.iVSet = true; + return this.initVector; + } + + // gets the first byte in a uint + private static byte WordByte0(uint w) + => WordByte3(w / 256 / 256 / 256); + + // gets the second byte in a uint + private static byte WordByte1(uint w) + => WordByte3(w / 256 / 256); + + // gets the third byte in a uint + private static byte WordByte2(uint w) + => WordByte3(w / 256); + + // gets the fourth byte in a uint + private static byte WordByte3(uint w) + => (byte)(w % 256); + + // converts a byte array to a hex string + private static string ByteToHex(byte[] bytes) + { + StringBuilder s = new(); + foreach (var b in bytes) + { + _ = s.Append(b.ToString("x2", CultureInfo.InvariantCulture)); + } + + return s.ToString(); + } + + // converts a hex string to a byte array + private static byte[] HexToByte(ReadOnlySpan hex) + { + Span r = stackalloc byte[hex.Length / 2]; + for (var i = 0; i < hex.Length - 1; i += 2) + { + var a = GetHex(hex[i]); + var b = GetHex(hex[i + 1]); + r[i / 2] = (byte)((a * 16) + b); + } + + return r.ToArray(); + } + + private static byte[] HexToByte(ReadOnlySpan hex) + { + Span r = stackalloc byte[hex.Length / 2]; + for (var i = 0; i < hex.Length - 1; i += 2) + { + var a = GetHex((char)hex[i]); + var b = GetHex((char)hex[i + 1]); + r[i / 2] = (byte)((a * 16) + b); + } + + return r.ToArray(); + } + + // converts a single hex character to it's decimal value + private static byte GetHex(char x) + => x switch + { + <= '9' and >= '0' => (byte)(x - '0'), + <= 'z' and >= 'a' => (byte)(x - 'a' + 10), + <= 'Z' and >= 'A' => (byte)(x - 'A' + 10), + _ => 0, + }; + + private void SetupKey(Span cipherKey) + { + this.bfP = SetupP.ToArray(); + + // set up the S blocks + this.bfS0 = SetupS0.ToArray(); + this.bfS1 = SetupS1.ToArray(); + this.bfS2 = SetupS2.ToArray(); + this.bfS3 = SetupS3.ToArray(); + ThrowHelpers.ThrowInvalidOperation(cipherKey.Length > 56, Resources.BlowFish_Key_Too_Long!); + var j = 0; + for (var i = 0; i < 18; i++) + { + var d = (uint)((((((cipherKey[j % cipherKey.Length] * 256) + cipherKey[(j + 1) % cipherKey.Length]) * 256) + cipherKey[(j + 2) % cipherKey.Length]) * 256) + cipherKey[(j + 3) % cipherKey.Length]); + this.bfP[i] ^= d; + j = (j + 4) % cipherKey.Length; + } + + this.xlPar = 0; + this.xrPar = 0; + for (var i = 0; i < 18; i += 2) + { + this.Encipher(); + this.bfP[i] = this.xlPar; + this.bfP[i + 1] = this.xrPar; + } + + for (var i = 0; i < 256; i += 2) + { + this.Encipher(); + this.bfS0[i] = this.xlPar; + this.bfS0[i + 1] = this.xrPar; + } + + for (var i = 0; i < 256; i += 2) + { + this.Encipher(); + this.bfS1[i] = this.xlPar; + this.bfS1[i + 1] = this.xrPar; + } + + for (var i = 0; i < 256; i += 2) + { + this.Encipher(); + this.bfS2[i] = this.xlPar; + this.bfS2[i + 1] = this.xrPar; + } + + for (var i = 0; i < 256; i += 2) + { + this.Encipher(); + this.bfS3[i] = this.xlPar; + this.bfS3[i + 1] = this.xrPar; + } + } + + [Obsolete("Use CBC version.")] + private byte[] Crypt_ECB(byte[] text, bool decrypt) + { + var paddedLen = text.Length % 8 == 0 ? text.Length : text.Length + 8 - (text.Length % 8); + if (paddedLen != text.Length) + { + Array.Resize(ref text, paddedLen); + } + + var plainText = text.AsSpan(); + for (var i = 0; i < plainText.Length; i += 8) + { + var block = plainText.Slice(i, 8); + if (decrypt) + { + this.BlockDecrypt(block); + } + else + { + this.BlockEncrypt(block); + } + } + + return text; + } + + private byte[] Crypt_CBC(byte[] text, bool decrypt) + { + ThrowHelpers.ThrowInvalidOperation(!this.iVSet, Resources.BlowFish_IV_Not_Set!); + var paddedLen = text.Length % 8 == 0 ? text.Length : text.Length + 8 - (text.Length % 8); + if (paddedLen != text.Length) + { + Array.Resize(ref text, paddedLen); + } + + var plainText = text.AsSpan(); + byte[]? preblock = null; + var iv = this.initVector.AsSpan().Slice(0, 8); + for (var i = 0; i < plainText.Length; i += 8) + { + var block = plainText.Slice(i, 8); + if (decrypt) + { + preblock = block.ToArray(); + this.BlockDecrypt(block); + } + + for (var v = 0; v < block.Length; v++) + { + block[v] ^= iv[v % iv.Length]; + } + + if (!decrypt) + { + this.BlockEncrypt(block); + iv = block; + } + else + { + // clone preblock into iv. + iv = preblock.AsSpan(); + } + } + + return text; + } + + private void BlockEncrypt(Span block) + { + this.SetBlock(block); + this.Encipher(); + this.GetBlock(block); + } + + private void BlockDecrypt(Span block) + { + this.SetBlock(block); + this.Decipher(); + this.GetBlock(block); + } + + private void SetBlock(Span block) + { + // split the block + if (!this.NonStandard) + { + // ToUInt32 requires the bytes in reverse order + block.Reverse(); + } + + this.xrPar = BitConverter.ToUInt32(block.ToArray(), 0); + this.xlPar = BitConverter.ToUInt32(block.ToArray(), 4); + if (!this.NonStandard) + { + // reverse them back. + block.Reverse(); + } + } + + private void GetBlock(Span block) + { + byte[] block1; + byte[] block2; + if (this.NonStandard) + { + block1 = BitConverter.GetBytes(this.xrPar); + block2 = BitConverter.GetBytes(this.xlPar); + } + else + { + block1 = BitConverter.GetBytes(this.xlPar); + block2 = BitConverter.GetBytes(this.xrPar); + + // GetBytes returns the bytes in reverse order + Array.Reverse(block1); + Array.Reverse(block2); + } + + // join the block + Array.Resize(ref block1, block1.Length + 4); + block2.CopyTo(block1, 4); + block1.CopyTo(block); + } + + private void Encipher() + { + this.xlPar ^= this.bfP[0]; + for (uint i = 0; i < 16; i += 2) + { + this.xrPar = this.Round(this.xrPar, this.xlPar, i + 1); + this.xlPar = this.Round(this.xlPar, this.xrPar, i + 2); + } + + this.xrPar ^= this.bfP[17]; + + // swap the blocks + (this.xlPar, this.xrPar) = (this.xrPar, this.xlPar); + } + + private void Decipher() + { + this.xlPar ^= this.bfP[17]; + for (uint i = 16; i > 2; i -= 2) + { + this.xrPar = this.Round(this.xrPar, this.xlPar, i); + this.xlPar = this.Round(this.xlPar, this.xrPar, i - 1); + } + + this.xrPar ^= this.bfP[0]; + + // swap the blocks + (this.xlPar, this.xrPar) = (this.xrPar, this.xlPar); + } + + private uint Round(uint a, uint b, uint n) + { + var x1 = (this.bfS0[WordByte0(b)] + this.bfS1[WordByte1(b)]) ^ this.bfS2[WordByte2(b)]; + var x2 = x1 + this.bfS3[WordByte3(b)]; + var x3 = x2 ^ this.bfP[n]; + return x3 ^ a; + } +} diff --git a/src/BlowFish/Directory.Build.targets b/src/BlowFish/Directory.Build.targets index 66e9b222..0d275e54 100644 --- a/src/BlowFish/Directory.Build.targets +++ b/src/BlowFish/Directory.Build.targets @@ -7,6 +7,7 @@ stylecop.json + diff --git a/src/Common/Common/MemoryStreamExtensions.cs b/src/Common/Common/MemoryStreamExtensions.cs index 08b7085d..43246e4f 100644 --- a/src/Common/Common/MemoryStreamExtensions.cs +++ b/src/Common/Common/MemoryStreamExtensions.cs @@ -20,7 +20,7 @@ public static class MemoryStreamExtensions public static void Clear(this MemoryStream ms, int capacity) { ArgumentNullException.ThrowIfNull(ms); - ThrowHelpers.ThrowArgumentOutOfRange(capacity < 0, nameof(capacity), "capacity must not be negative."); + ArgumentOutOfRangeException.ThrowIfLessThan(capacity, 0); var len = ms.GetBuffer().Length; var changeCapacity = len != capacity; Array.Clear(ms.GetBuffer(), 0, len); diff --git a/src/Common/Common/MessageEventHandler.cs b/src/Common/Common/MessageEventHandler.cs deleted file mode 100644 index 38fdbd40..00000000 --- a/src/Common/Common/MessageEventHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2018-2023, Els_kom org. -// https://github.com/Elskom/ -// All rights reserved. -// license: MIT, see LICENSE for more details. - -namespace Elskom.Generic.Libs; - -/// -/// Represents the method that will handle an event when the event provides data. -/// -/// -/// The source of the event. -/// -/// -/// An object that contains the event data. -/// -public delegate void MessageEventHandler(object? sender, ref MessageEventArgs e); diff --git a/src/Common/Common/NotificationEventArgs.cs b/src/Common/Common/NotificationEventArgs.cs index 7e3f4b9a..0ce4409e 100644 --- a/src/Common/Common/NotificationEventArgs.cs +++ b/src/Common/Common/NotificationEventArgs.cs @@ -8,7 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Event that holds that data to call the apis for notifications. /// -public class NotificationEventArgs +public class NotificationEventArgs : EventArgs { /// /// Initializes a new instance of the class. diff --git a/src/Common/Common/NotificationEventHandler.cs b/src/Common/Common/NotificationEventHandler.cs deleted file mode 100644 index 6252cfc3..00000000 --- a/src/Common/Common/NotificationEventHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2018-2023, Els_kom org. -// https://github.com/Elskom/ -// All rights reserved. -// license: MIT, see LICENSE for more details. - -namespace Elskom.Generic.Libs; - -/// -/// Represents the method that will handle an event when the event provides data. -/// -/// -/// The source of the event. -/// -/// -/// An object that contains the event data. -/// -public delegate void NotificationEventHandler(object? sender, ref NotificationEventArgs e); diff --git a/src/Common/Common/ProcessStartOptions.cs b/src/Common/Common/ProcessStartOptions.cs index 4f2ddbaf..c371cf02 100644 --- a/src/Common/Common/ProcessStartOptions.cs +++ b/src/Common/Common/ProcessStartOptions.cs @@ -81,7 +81,7 @@ public ProcessStartOptions WithStartInformation(string fileName, string argument /// Executes the process. /// /// The process's redirected outputs. - /// When the instance's startup information is null. + /// When the instance's startup information is null. /// When the file to the process to execute does not exist on disk. public string Start() => this.Start(this.StartInfo); @@ -91,11 +91,11 @@ public string Start() /// /// The process start information to use to start the process. /// The process's redirected outputs. - /// When the instance's startup information is null. + /// When the instance's startup information is null. /// When the file to the process to execute does not exist on disk. public string Start(ProcessStartInfo startInfo) { - ThrowHelpers.ThrowInvalidOperation(startInfo is null, "StartInfo must not be null."); + ArgumentNullException.ThrowIfNull(startInfo); ThrowHelpers.ThrowFileNotFound(!File.Exists(startInfo!.FileName), "File to execute does not exist."); this.Executing = true; using var proc = new Process(); diff --git a/src/Common/Common/ThrowHelpers.cs b/src/Common/Common/ThrowHelpers.cs index 12e0d6e6..fde6a1a1 100644 --- a/src/Common/Common/ThrowHelpers.cs +++ b/src/Common/Common/ThrowHelpers.cs @@ -7,51 +7,31 @@ namespace Elskom.Generic.Libs; internal static class ThrowHelpers { - internal static void ThrowArgumentNull(bool value, string paramName) - { - if (value) - { - throw new ArgumentNullException(paramName); - } - } - + [StackTraceHidden] internal static void ThrowInvalidOperation(bool value, string message) { if (value) { - throw new InvalidOperationException(message); - } - } - - internal static void ThrowArgumentOutOfRange(bool value, string paramName) - { - if (value) - { - throw new ArgumentOutOfRangeException(paramName); - } - } - - internal static void ThrowArgumentOutOfRange(bool value, string paramName, string message) - { - if (value) - { - throw new ArgumentOutOfRangeException(paramName, message); + ThrowInvalidOperationCore(message); } } + [StackTraceHidden] internal static void ThrowFileNotFound(bool value, string message) { if (value) { - throw new FileNotFoundException(message); + ThrowFileNotFoundCore(message); } } - internal static void ThrowObjectDisposed(bool value, string objectName) - { - if (value) - { - throw new ObjectDisposedException(objectName); - } - } + [StackTraceHidden] + [DoesNotReturn] + private static void ThrowInvalidOperationCore(string message) + => throw new InvalidOperationException(message); + + [StackTraceHidden] + [DoesNotReturn] + private static void ThrowFileNotFoundCore(string message) + => throw new FileNotFoundException(message); } diff --git a/src/Common/Directory.Build.targets b/src/Common/Directory.Build.targets index 991d01f3..3b2690f3 100644 --- a/src/Common/Directory.Build.targets +++ b/src/Common/Directory.Build.targets @@ -20,6 +20,7 @@ <_Parameter1>ReleasePackaging,PublicKey=$(SnkPublicKey) + diff --git a/src/GenericPluginLoader/Directory.Build.targets b/src/GenericPluginLoader/Directory.Build.targets index daf30b81..6cd538f8 100644 --- a/src/GenericPluginLoader/Directory.Build.targets +++ b/src/GenericPluginLoader/Directory.Build.targets @@ -10,6 +10,7 @@ + diff --git a/src/GenericPluginLoader/GenericPluginLoader/GenericPluginLoader.cs b/src/GenericPluginLoader/GenericPluginLoader/GenericPluginLoader.cs index d2a6ecdf..c6c4593f 100644 --- a/src/GenericPluginLoader/GenericPluginLoader/GenericPluginLoader.cs +++ b/src/GenericPluginLoader/GenericPluginLoader/GenericPluginLoader.cs @@ -18,7 +18,7 @@ public sealed class GenericPluginLoader /// /// Triggers when the Plugin Loader has a message to send to the application. /// - public static event MessageEventHandler? PluginLoaderMessage; + public static event EventHandler? PluginLoaderMessage; internal Dictionary> Contexts { get; } = new(); @@ -86,7 +86,7 @@ public ICollection LoadPlugins(string path, bool saveToZip) dllFile, dllFile.Replace(".dll", ".pdb", StringComparison.InvariantCulture)); context.UnloadIfNoInstances(instances); - if (instances.Any()) + if (instances.Count != 0) { plugins.AddRange(instances); contexts.Add(context); @@ -115,7 +115,7 @@ public ICollection LoadPlugins(string path, bool saveToZip) PluginLoadContext context = new($"ZipPlugin#{filesInZip[entry]}", path); var instances = RuntimeExtensions.CreateInstancesFromInterface(ZipAssembly.LoadFromZip(zippath, entry, context)); context.UnloadIfNoInstances(instances); - if (instances.Any()) + if (instances.Count != 0) { plugins.AddRange(instances); contexts.Add(context); @@ -152,7 +152,7 @@ public void UnloadPlugins() } internal static void InvokeLoaderMessage(ref MessageEventArgs args) - => PluginLoaderMessage?.Invoke(null, ref args); + => PluginLoaderMessage?.Invoke(null, args); private void UnloadPluginsInternal(string key) { diff --git a/src/GenericPluginLoader/GenericPluginLoader/PluginLoadContext.cs b/src/GenericPluginLoader/GenericPluginLoader/PluginLoadContext.cs index b0139da9..3eda1471 100644 --- a/src/GenericPluginLoader/GenericPluginLoader/PluginLoadContext.cs +++ b/src/GenericPluginLoader/GenericPluginLoader/PluginLoadContext.cs @@ -6,7 +6,7 @@ namespace Elskom.Generic.Libs; /// -internal class PluginLoadContext : AssemblyLoadContext +internal sealed class PluginLoadContext : AssemblyLoadContext { private readonly AssemblyDependencyResolver resolver; diff --git a/src/GenericPluginLoader/GenericPluginLoader/RuntimeExtensions.cs b/src/GenericPluginLoader/GenericPluginLoader/RuntimeExtensions.cs index 2218f3cf..65f56599 100644 --- a/src/GenericPluginLoader/GenericPluginLoader/RuntimeExtensions.cs +++ b/src/GenericPluginLoader/GenericPluginLoader/RuntimeExtensions.cs @@ -12,9 +12,9 @@ public static List CreateInstancesFromInterface(this AssemblyLoadContext c List instances = new(); try { - var asmFiles = OpenAssemblyFiles(dllFile, pdbFile); - using MemoryStream ms1 = new(asmFiles.AsmBytes!); - MemoryStream? ms2 = Debugger.IsAttached && asmFiles.PdbBytes is not null ? new(asmFiles.PdbBytes) : null; + var (asmBytes, pdbBytes) = OpenAssemblyFiles(dllFile, pdbFile); + using MemoryStream ms1 = new(asmBytes!); + MemoryStream? ms2 = Debugger.IsAttached && pdbBytes is not null ? new(pdbBytes) : null; instances.AddRange(context.CreateInstancesFromInterface(ms1, ms2)); ms2?.Dispose(); } @@ -59,6 +59,7 @@ public static List CreateInstancesFromInterface(Assembly? assembly) foreach (var exceptions in ex.LoaderExceptions) { _ = exMsg.AppendLine( + CultureInfo.InvariantCulture, $"{ex.GetType()}: {exceptions?.Message}"); _ = exMsg.AppendLine(exceptions?.StackTrace); } @@ -78,7 +79,7 @@ public static List CreateInstancesFromInterface(Assembly? assembly) public static void UnloadIfNoInstances(this AssemblyLoadContext context, List instances) { - if (!instances.Any() && context.IsCollectible) + if (instances.Count == 0 && context.IsCollectible) { context.Unload(); } diff --git a/src/GitInformation/GitInformationAttribute.cs b/src/GitInformation/GitInformationAttribute.cs index a01c1a8c..aaf5edda 100644 --- a/src/GitInformation/GitInformationAttribute.cs +++ b/src/GitInformation/GitInformationAttribute.cs @@ -11,7 +11,7 @@ namespace Elskom.Generic.Libs; /// Attribute that creates and registers an instance of the class for the assembly. /// [AttributeUsage(AttributeTargets.Assembly, Inherited = false)] -public class GitInformationAttribute : Attribute +public sealed class GitInformationAttribute : Attribute { /// /// Initializes a new instance of the class. @@ -31,8 +31,10 @@ public class GitInformationAttribute : Attribute /// /// Thrown when is . /// + [SuppressMessage("Design", "CA1019:Define accessors for attribute arguments", Justification = "Do not want the values of the mandatory arguments to be retrievable.")] public GitInformationAttribute(string headdesc, string commit, string branchname, Type assemblyType) { + ArgumentNullException.ThrowIfNull(assemblyType); GitInformation.ApplyAssemblyAttributes(typeof(GitInformation).Assembly); GitInformation.GetOrCreateAssemblyInstance(headdesc, commit, branchname, assemblyType.Assembly); } diff --git a/src/MessageManager/MessageManager/MessageManager.cs b/src/MessageManager/MessageManager/MessageManager.cs index 745636ea..4e19a6a0 100644 --- a/src/MessageManager/MessageManager/MessageManager.cs +++ b/src/MessageManager/MessageManager/MessageManager.cs @@ -13,7 +13,7 @@ public static class MessageManager /// /// Occurs when the ShowError(), ShowInfo(), or ShowWarning() methods is told to use Notifications. /// - public static event NotificationEventHandler? Notification; + public static event EventHandler? Notification; /// /// Shows an MessageBox that is for an Question. @@ -65,7 +65,7 @@ private static int ShowCore(int timeout, string text, string caption, int tipIco useNotifications, messageBoxButtons, messageBoxIcon); - Notification?.Invoke(null, ref args); + Notification?.Invoke(null, args); return args.Result; } } diff --git a/src/MiniDump/Directory.Build.targets b/src/MiniDump/Directory.Build.targets index eb3b99d8..7585d979 100644 --- a/src/MiniDump/Directory.Build.targets +++ b/src/MiniDump/Directory.Build.targets @@ -8,6 +8,7 @@ stylecop.json + diff --git a/src/MiniDump/MiniDump/MiniDumpAttribute.cs b/src/MiniDump/MiniDump/MiniDumpAttribute.cs index 220d80f7..b0a54a23 100644 --- a/src/MiniDump/MiniDump/MiniDumpAttribute.cs +++ b/src/MiniDump/MiniDump/MiniDumpAttribute.cs @@ -64,12 +64,12 @@ public MiniDumpAttribute() /// } /// /// - public static event MiniDumpEventHandler? Dump; + public static event EventHandler? Dump; /// /// Occurs when a mini-dump is generated or fails. /// - public static event MessageEventHandler? DumpMessage; + public static event EventHandler? DumpMessage; /// /// Gets the current instance of this attribute. @@ -128,11 +128,11 @@ public static int DumpException(Exception exception, bool threadException) => MiniDump.ExceptionEventHandlerCode(exception, threadException); internal static void InvokeDumpMessage(ref MessageEventArgs e) - => DumpMessage?.Invoke(null, ref e); + => DumpMessage?.Invoke(null, e); internal static bool InvokeDump(ref MiniDumpEventArgs e) { - Dump?.Invoke(null, ref e); + Dump?.Invoke(null, e); return e.Success; } } diff --git a/src/MiniDump/MiniDump/MiniDumpEventArgs.cs b/src/MiniDump/MiniDump/MiniDumpEventArgs.cs index 4093f7d1..cae7fd8a 100644 --- a/src/MiniDump/MiniDump/MiniDumpEventArgs.cs +++ b/src/MiniDump/MiniDump/MiniDumpEventArgs.cs @@ -8,7 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Event that holds the information needed to create a dump. /// -public class MiniDumpEventArgs +public class MiniDumpEventArgs : EventArgs { internal MiniDumpEventArgs(int processId, string fileName, MiniDumpType dumpType) { diff --git a/src/MiniDump/MiniDump/MiniDumpEventHandler.cs b/src/MiniDump/MiniDump/MiniDumpEventHandler.cs deleted file mode 100644 index b2e1353f..00000000 --- a/src/MiniDump/MiniDump/MiniDumpEventHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2018-2023, Els_kom org. -// https://github.com/Elskom/ -// All rights reserved. -// license: MIT, see LICENSE for more details. - -namespace Elskom.Generic.Libs; - -/// -/// Represents the method that will handle an event when the event provides data. -/// -/// -/// The source of the event. -/// -/// -/// An object that contains the event data. -/// -public delegate void MiniDumpEventHandler(object? sender, ref MiniDumpEventArgs e); diff --git a/src/MiniDump/MiniDump/MiniDumpType.cs b/src/MiniDump/MiniDump/MiniDumpType.cs index 277b7733..f159f16f 100644 --- a/src/MiniDump/MiniDump/MiniDumpType.cs +++ b/src/MiniDump/MiniDump/MiniDumpType.cs @@ -8,6 +8,7 @@ namespace Elskom.Generic.Libs; /// /// Represents the type of dump that can be requested. /// +[SuppressMessage("Design", "CA1008:Enums should have zero value", Justification = "Controls MiniDump Types.")] public enum MiniDumpType { /// diff --git a/src/PluginFramework/.editorconfig b/src/PluginFramework/.editorconfig index 8104f411..23745322 100644 --- a/src/PluginFramework/.editorconfig +++ b/src/PluginFramework/.editorconfig @@ -149,3 +149,6 @@ dotnet_diagnostic.S101.severity = none # S3903: Move '%s' into a named namespace. dotnet_diagnostic.S3903.severity = none + +# S1135: Track uses of "TODO" tags +dotnet_diagnostic.S1135.severity = suggestion diff --git a/src/PluginFramework/Directory.Build.targets b/src/PluginFramework/Directory.Build.targets index 15a0d8f0..39c7bcd5 100644 --- a/src/PluginFramework/Directory.Build.targets +++ b/src/PluginFramework/Directory.Build.targets @@ -8,6 +8,7 @@ stylecop.json + diff --git a/src/PluginFramework/PluginFramework/ExecutionManager.cs b/src/PluginFramework/PluginFramework/ExecutionManager.cs index c2afbe78..34be2441 100644 --- a/src/PluginFramework/PluginFramework/ExecutionManager.cs +++ b/src/PluginFramework/PluginFramework/ExecutionManager.cs @@ -10,6 +10,15 @@ namespace Elskom.Generic.Libs; /// public static class ExecutionManager { + private static readonly CompositeFormat ExecutionManagerElsDirNotSet = CompositeFormat.Parse( + Resources.ExecutionManager_ElsDir_Not_Set); + + private static readonly CompositeFormat ExecutionManagerCannotFindElswordExe = CompositeFormat.Parse( + Resources.ExecutionManager_Cannot_Find_elsword_exe); + + private static readonly CompositeFormat ExecutionManagerCannotFindX2Exe = CompositeFormat.Parse( + Resources.ExecutionManager_Cannot_Find_x2_exe); + /// /// Gets a value indicating whether the launcher to Elsword is running. /// @@ -114,7 +123,8 @@ public static void RunElswordDirectly() { MessageEventArgs args = new( string.Format( - Resources.ExecutionManager_Cannot_Find_x2_exe!, + CultureInfo.InvariantCulture, + ExecutionManagerCannotFindX2Exe!, ElsDir, Path.DirectorySeparatorChar), Resources.Error!, @@ -128,7 +138,8 @@ public static void RunElswordDirectly() { MessageEventArgs args = new( string.Format( - Resources.ExecutionManager_ElsDir_Not_Set!, + CultureInfo.InvariantCulture, + ExecutionManagerElsDirNotSet!, "Test your mods"), Resources.Error!, ErrorLevel.Error); @@ -168,7 +179,8 @@ public static void RunElswordLauncher() { MessageEventArgs args = new( string.Format( - Resources.ExecutionManager_Cannot_Find_elsword_exe!, + CultureInfo.InvariantCulture, + ExecutionManagerCannotFindElswordExe!, ElsDir, Path.DirectorySeparatorChar), Resources.Error!, @@ -183,7 +195,8 @@ public static void RunElswordLauncher() { MessageEventArgs args = new( string.Format( - Resources.ExecutionManager_ElsDir_Not_Set!, + CultureInfo.InvariantCulture, + ExecutionManagerElsDirNotSet!, "update Elsword"), Resources.Error!, ErrorLevel.Error); diff --git a/src/PluginFramework/PluginFramework/KOMManager.cs b/src/PluginFramework/PluginFramework/KOMManager.cs index 3b8c61a0..253db809 100644 --- a/src/PluginFramework/PluginFramework/KOMManager.cs +++ b/src/PluginFramework/PluginFramework/KOMManager.cs @@ -10,6 +10,12 @@ namespace Elskom.Generic.Libs; /// public static class KOMManager { + private static readonly CompositeFormat KOMManagerPluginNoUnpackerFunction = CompositeFormat.Parse( + Resources.KOMManager_Plugin_No_Unpacker_Function); + + private static readonly CompositeFormat KOMManagerPluginNoPackerFunction = CompositeFormat.Parse( + Resources.KOMManager_Plugin_No_Packer_Function); + private static List? komplugins; private static List? encryptionplugins; private static List? callbackplugins; @@ -17,7 +23,7 @@ public static class KOMManager /// /// The event to which allows getting the message to do stuff with. /// - public static event MessageEventHandler? MessageEvent; + public static event EventHandler? MessageEvent; /// /// Gets a value indicating whether the current state on packing KOM files. @@ -37,7 +43,8 @@ public static class KOMManager /// /// The list of plugins. /// - public static List Komplugins => komplugins ??= new(); + public static IList Komplugins + => komplugins ??= []; /// /// Gets The list of plugins. @@ -45,7 +52,8 @@ public static class KOMManager /// /// The list of plugins. /// - public static List Encryptionplugins => encryptionplugins ??= new(); + public static IList Encryptionplugins + => encryptionplugins ??= []; /// /// Gets the list of plugins. @@ -53,7 +61,8 @@ public static class KOMManager /// /// The list of plugins. /// - public static List Callbackplugins => callbackplugins ??= new(); + public static IList Callbackplugins + => callbackplugins ??= []; /// /// Copies Modified KOM files to the Elsword Directory that was Set in the Settings Dialog in Els_kom. Requires: File Name, Original Directory the File is in, And Destination Directory. @@ -83,11 +92,12 @@ public static void CopyKomFiles(string fileName, string origFileDir, string dest /// The name of the file to move. /// The original kom file location. /// The target to move the kom file too. - /// When or are or empty. + /// When or are . + /// When or are empty. public static void MoveOriginalKomFilesBack(string fileName, string origFileDir, string destFileDir) { - ThrowHelpers.ThrowArgumentNull(string.IsNullOrEmpty(origFileDir), nameof(origFileDir)); - ThrowHelpers.ThrowArgumentNull(string.IsNullOrEmpty(destFileDir), nameof(destFileDir)); + ArgumentException.ThrowIfNullOrEmpty(origFileDir); + ArgumentException.ThrowIfNullOrEmpty(destFileDir); if (!origFileDir!.EndsWith($"{Path.DirectorySeparatorChar}", StringComparison.Ordinal)) { origFileDir += Path.DirectorySeparatorChar; @@ -164,7 +174,8 @@ public static void UnpackKoms() { MessageEventArgs args = new( string.Format( - Resources.KOMManager_Plugin_No_Unpacker_Function!, + CultureInfo.InvariantCulture, + KOMManagerPluginNoUnpackerFunction!, komplugin.SupportedKOMVersion), Resources.Error!, ErrorLevel.Error); @@ -239,7 +250,8 @@ public static void PackKoms() MessageEventArgs args = new( string.Format( - Resources.KOMManager_Plugin_No_Packer_Function!, + CultureInfo.InvariantCulture, + KOMManagerPluginNoPackerFunction!, komplugin.SupportedKOMVersion), Resources.Error!, ErrorLevel.Error); @@ -396,7 +408,7 @@ internal static int GetCRCVersion(string xmldata) } internal static void InvokeMessageEvent(ref MessageEventArgs e) - => MessageEvent?.Invoke(null, ref e); + => MessageEvent?.Invoke(null, e); private static void MoveOriginalKomFiles(string fileName, string origFileDir, string destFileDir) { diff --git a/src/PluginUpdateCheck/Directory.Build.targets b/src/PluginUpdateCheck/Directory.Build.targets index 2d293fb4..ca580777 100644 --- a/src/PluginUpdateCheck/Directory.Build.targets +++ b/src/PluginUpdateCheck/Directory.Build.targets @@ -7,8 +7,10 @@ stylecop.json + + diff --git a/src/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateCheck.cs b/src/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateCheck.cs index 3616542d..2f913275 100644 --- a/src/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateCheck.cs +++ b/src/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateCheck.cs @@ -11,6 +11,18 @@ namespace Elskom.Generic.Libs; [GenerateDispose(false)] public sealed partial class PluginUpdateCheck { + private static readonly CompositeFormat PluginUpdateCheckShowMessageUpdateForPluginIsAvailible = CompositeFormat.Parse( + Resources.PluginUpdateCheck_ShowMessage_Update_for_plugin_is_availible); + + private static readonly CompositeFormat PluginUpdateCheckCheckForUpdatesFailedToDownloadThePluginsSourcesListReason = CompositeFormat.Parse( + Resources.PluginUpdateCheck_CheckForUpdates_Failed_to_download_the_plugins_sources_list_Reason); + + private static readonly CompositeFormat PluginUpdateCheckInstallFailedToInstallTheSelectedPluginReason = CompositeFormat.Parse( + Resources.PluginUpdateCheck_Install_Failed_to_install_the_selected_plugin_Reason); + + private static readonly CompositeFormat PluginUpdateCheckUninstallFailedToUninstallTheSelectedPluginReason = CompositeFormat.Parse( + Resources.PluginUpdateCheck_Uninstall_Failed_to_uninstall_the_selected_plugin_Reason); + private readonly IServiceProvider serviceProvider; /// @@ -26,13 +38,13 @@ public PluginUpdateCheck(IServiceProvider serviceprovider) /// /// Event that fires when a new message should show up. /// - public static event MessageEventHandler? MessageEvent; + public static event EventHandler? MessageEvent; /// /// Gets the plugin urls used in all instances. /// [NullOnDispose] - public List? PluginUrls { get; private set; } + public IList? PluginUrls { get; private set; } /// /// Gets a value indicating whether there are any pending updates and displays a message if there is. @@ -41,9 +53,9 @@ public bool ShowMessage { get { - ThrowHelpers.ThrowObjectDisposed(this.isDisposed, nameof(PluginUpdateCheck)); + ObjectDisposedException.ThrowIf(this.isDisposed, typeof(PluginUpdateCheck)); var result = false; - if (!this.PluginUpdateDatas.Any()) + if (this.PluginUpdateDatas.Count == 0) { return false; } @@ -59,12 +71,12 @@ public bool ShowMessage var args = new MessageEventArgs( string.Format( CultureInfo.InvariantCulture, - Resources.PluginUpdateCheck_ShowMessage_Update_for_plugin_is_availible!, + PluginUpdateCheckShowMessageUpdateForPluginIsAvailible!, pluginUpdateData.CurrentVersion, pluginUpdateData.PluginName), Resources.PluginUpdateCheck_ShowMessage_New_plugin_update!, ErrorLevel.Info); - MessageEvent?.Invoke(null, ref args); + MessageEvent?.Invoke(null, args); result = true; } @@ -76,7 +88,7 @@ public bool ShowMessage /// Gets a list of instances representing the plugins that needs updating or are to be installed. /// [NullOnDispose] - public List PluginUpdateDatas { get; private set; } + public IList PluginUpdateDatas { get; private set; } /// /// Checks for plugin updates from the provided plugin source urls. @@ -94,7 +106,7 @@ public bool ShowMessage /// A value indicating if the operation was successful or not. /// // catches the plugin urls and uses that cache to detect added urls, and only appends those to the list. - public bool CheckForUpdates(string[] pluginURLs, List pluginTypes) + public bool CheckForUpdates(string[] pluginURLs, IList pluginTypes) { ArgumentNullException.ThrowIfNull(pluginURLs); ArgumentNullException.ThrowIfNull(pluginTypes); @@ -107,20 +119,20 @@ public bool CheckForUpdates(string[] pluginURLs, List pluginTypes) "https://github.com/", "https://raw.githubusercontent.com/", StringComparison.Ordinal); - var arg1 = pluginURLs[i].EndsWith("/", StringComparison.Ordinal) + var arg1 = pluginURLs[i].EndsWith('/') ? "main/plugins.xml" : "/main/plugins.xml"; pluginURLs1[i] = $"{arg0}{arg1}"; } - this.PluginUrls ??= new(); + this.PluginUrls ??= new List(); foreach (var pluginURL in pluginURLs1) { if (!this.PluginUrls.Contains(pluginURL)) { try { - var doc = XDocument.Parse(this.serviceProvider.GetRequiredService()?.GetStringAsync(pluginURL).GetAwaiter().GetResult()!); + var doc = XDocument.Parse(this.serviceProvider.GetRequiredService()?.GetStringAsync(new Uri(pluginURL)).GetAwaiter().GetResult()!); var elements = doc.Root!.Elements("Plugin"); foreach (var element in elements) { @@ -162,12 +174,12 @@ public bool CheckForUpdates(string[] pluginURLs, List pluginTypes) var args = new MessageEventArgs( string.Format( CultureInfo.InvariantCulture, - Resources.PluginUpdateCheck_CheckForUpdates_Failed_to_download_the_plugins_sources_list_Reason!, + PluginUpdateCheckCheckForUpdatesFailedToDownloadThePluginsSourcesListReason!, Environment.NewLine, ex.Message), Resources.PluginUpdateCheck_CheckForUpdates_Error!, ErrorLevel.Error); - MessageEvent?.Invoke(null, ref args); + MessageEvent?.Invoke(null, args); return false; } @@ -193,7 +205,7 @@ public bool CheckForUpdates(string[] pluginURLs, List pluginTypes) /// public bool Install(PluginUpdateData pluginUpdateData, bool saveToZip) { - ThrowHelpers.ThrowObjectDisposed(this.isDisposed, nameof(PluginUpdateCheck)); + ObjectDisposedException.ThrowIf(this.isDisposed, typeof(PluginUpdateCheck)); foreach (var downloadFile in pluginUpdateData.DownloadFiles) { try @@ -201,7 +213,7 @@ public bool Install(PluginUpdateData pluginUpdateData, bool saveToZip) var path = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}plugins{Path.DirectorySeparatorChar}{downloadFile}"; using (var fs = File.Create(path)) using (var response = this.serviceProvider.GetRequiredService()?.GetStreamAsync( - $"{pluginUpdateData.DownloadUrl}{downloadFile}").GetAwaiter().GetResult()) + new Uri($"{pluginUpdateData.DownloadUrl}{downloadFile}")).GetAwaiter().GetResult()) { response?.CopyTo(fs); } @@ -227,12 +239,12 @@ public bool Install(PluginUpdateData pluginUpdateData, bool saveToZip) var args = new MessageEventArgs( string.Format( CultureInfo.InvariantCulture, - Resources.PluginUpdateCheck_Install_Failed_to_install_the_selected_plugin_Reason!, + PluginUpdateCheckInstallFailedToInstallTheSelectedPluginReason!, Environment.NewLine, ex.Message), Resources.PluginUpdateCheck_CheckForUpdates_Error!, ErrorLevel.Error); - MessageEvent?.Invoke(null, ref args); + MessageEvent?.Invoke(null, args); } } @@ -252,9 +264,10 @@ public bool Install(PluginUpdateData pluginUpdateData, bool saveToZip) /// /// A bool indicating if anything changed. /// + [SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "This should have proper error checking.")] public bool Uninstall(PluginUpdateData pluginUpdateData, bool saveToZip) { - ThrowHelpers.ThrowObjectDisposed(this.isDisposed, nameof(PluginUpdateCheck)); + ObjectDisposedException.ThrowIf(this.isDisposed, typeof(PluginUpdateCheck)); try { foreach (var downloadFile in pluginUpdateData.DownloadFiles) @@ -290,12 +303,12 @@ public bool Uninstall(PluginUpdateData pluginUpdateData, bool saveToZip) var args = new MessageEventArgs( string.Format( CultureInfo.InvariantCulture, - Resources.PluginUpdateCheck_Uninstall_Failed_to_uninstall_the_selected_plugin_Reason!, + PluginUpdateCheckUninstallFailedToUninstallTheSelectedPluginReason!, Environment.NewLine, ex.Message), Resources.PluginUpdateCheck_CheckForUpdates_Error!, ErrorLevel.Error); - MessageEvent?.Invoke(null, ref args); + MessageEvent?.Invoke(null, args); } return false; diff --git a/src/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateData.cs b/src/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateData.cs index cb9733fe..2f04750e 100644 --- a/src/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateData.cs +++ b/src/PluginUpdateCheck/PluginUpdateCheck/PluginUpdateData.cs @@ -8,7 +8,7 @@ namespace Elskom.Generic.Libs; /// /// The Plugin Update data for a plugin. /// -public struct PluginUpdateData +public struct PluginUpdateData : IEquatable { /// /// Gets the plugin name this instance is pointing to. @@ -33,5 +33,28 @@ public struct PluginUpdateData /// /// Gets the files to the plugin to download. /// - public List DownloadFiles { get; internal set; } + public IList DownloadFiles { get; internal set; } + + public static bool operator ==(PluginUpdateData left, PluginUpdateData right) + => left.Equals(right); + + public static bool operator !=(PluginUpdateData left, PluginUpdateData right) + => !(left == right); + + /// + public override readonly bool Equals(object? obj) + => obj is PluginUpdateData data + && this.PluginName == data.PluginName + && this.CurrentVersion == data.CurrentVersion + && this.InstalledVersion == data.InstalledVersion + && EqualityComparer.Default.Equals(this.DownloadUrl, data.DownloadUrl) + && EqualityComparer>.Default.Equals(this.DownloadFiles, data.DownloadFiles); + + /// + public readonly bool Equals(PluginUpdateData other) + => this.Equals((object)other); + + /// + public override readonly int GetHashCode() + => HashCode.Combine(this.PluginName, this.CurrentVersion, this.InstalledVersion, this.DownloadUrl, this.DownloadFiles); } diff --git a/src/ReleasePackaging/ReleasePackaging/ReleasePackaging.cs b/src/ReleasePackaging/ReleasePackaging/ReleasePackaging.cs index 29f60627..2046178a 100644 --- a/src/ReleasePackaging/ReleasePackaging/ReleasePackaging.cs +++ b/src/ReleasePackaging/ReleasePackaging/ReleasePackaging.cs @@ -23,7 +23,7 @@ private static List Extensions /// When the length of args is greater than or less than 2. public static void PackageRelease(ReadOnlySpan args) { - ThrowHelpers.ThrowArgumentOutOfRange(args.Length is not 2, nameof(args), "The length of the input arguments to package the release is greater than or less than 2."); + ArgumentOutOfRangeException.ThrowIfNotEqual(args.Length, 2); // Replace spaces with periods. var outfilename = args[1].Replace(" ", ".", StringComparison.OrdinalIgnoreCase); diff --git a/src/SettingsFile/Directory.Build.targets b/src/SettingsFile/Directory.Build.targets index 88ee3f55..6f4fdb06 100644 --- a/src/SettingsFile/Directory.Build.targets +++ b/src/SettingsFile/Directory.Build.targets @@ -11,6 +11,7 @@ <_Parameter1>MiniDump,PublicKey=$(SnkPublicKey) + diff --git a/src/SettingsFile/SettingsFile/JsonSettings.cs b/src/SettingsFile/SettingsFile/JsonSettings.cs index 484ab0cc..4a58ebc8 100644 --- a/src/SettingsFile/SettingsFile/JsonSettings.cs +++ b/src/SettingsFile/SettingsFile/JsonSettings.cs @@ -56,6 +56,7 @@ public class JsonSettings /// Gets or sets the sources to use to install plugins from. /// [JsonPropertyName(nameof(Sources))] + [SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "Needed for settings json file.")] public string[] Sources { get; set; } = null!; /// diff --git a/src/UnluacNET/.editorconfig b/src/UnluacNET/.editorconfig index bda522f9..dfe3b722 100644 --- a/src/UnluacNET/.editorconfig +++ b/src/UnluacNET/.editorconfig @@ -173,3 +173,9 @@ dotnet_diagnostic.S3903.severity = none # IDISP008: Don't assign member with injected and created disposables dotnet_diagnostic.IDISP008.severity = none + +# S1135: Track uses of "TODO" tags +dotnet_diagnostic.S1135.severity = suggestion + +# CA1812: Avoid uninstantiated internal classes +dotnet_diagnostic.CA1812.severity = suggestion diff --git a/src/UnluacNET/Decompile/Block/AlwaysLoop.cs b/src/UnluacNET/Decompile/Block/AlwaysLoop.cs index 57b8d2f0..da4c9288 100644 --- a/src/UnluacNET/Decompile/Block/AlwaysLoop.cs +++ b/src/UnluacNET/Decompile/Block/AlwaysLoop.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class AlwaysLoop : Block +internal sealed class AlwaysLoop : Block { private readonly List m_statements; diff --git a/src/UnluacNET/Decompile/Block/Block.cs b/src/UnluacNET/Decompile/Block/Block.cs index c879e33b..660bfab8 100644 --- a/src/UnluacNET/Decompile/Block/Block.cs +++ b/src/UnluacNET/Decompile/Block/Block.cs @@ -79,6 +79,7 @@ public virtual Operation Process(Decompiler d) return new LambdaOperation(this.End - 1, (_, _) => statement); } + [SuppressMessage("Maintainability", "CA1508:Avoid dead conditional code", Justification = "False Positive.")] public override bool Equals(object obj) => ReferenceEquals(this, obj) && obj is not null && this.CompareTo((Block)obj) is 0; diff --git a/src/UnluacNET/Decompile/Block/BooleanIndicator.cs b/src/UnluacNET/Decompile/Block/BooleanIndicator.cs index fa471360..55139bd0 100644 --- a/src/UnluacNET/Decompile/Block/BooleanIndicator.cs +++ b/src/UnluacNET/Decompile/Block/BooleanIndicator.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class BooleanIndicator : Block +internal sealed class BooleanIndicator : Block { public BooleanIndicator(LFunction function, int line) : base(function, line, line) diff --git a/src/UnluacNET/Decompile/Block/Break.cs b/src/UnluacNET/Decompile/Block/Break.cs index 699d0dec..f3239513 100644 --- a/src/UnluacNET/Decompile/Block/Break.cs +++ b/src/UnluacNET/Decompile/Block/Break.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Break : Block +internal sealed class Break : Block { public Break(LFunction function, int line, int target) : base(function, line, line) diff --git a/src/UnluacNET/Decompile/Block/CompareBlock.cs b/src/UnluacNET/Decompile/Block/CompareBlock.cs index 70705caf..97cd3c00 100644 --- a/src/UnluacNET/Decompile/Block/CompareBlock.cs +++ b/src/UnluacNET/Decompile/Block/CompareBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class CompareBlock : Block +internal sealed class CompareBlock : Block { public CompareBlock(LFunction function, int begin, int end, int target, Branch branch) : base(function, begin, end) diff --git a/src/UnluacNET/Decompile/Block/DoEndBlock.cs b/src/UnluacNET/Decompile/Block/DoEndBlock.cs index 35b184af..f78f557f 100644 --- a/src/UnluacNET/Decompile/Block/DoEndBlock.cs +++ b/src/UnluacNET/Decompile/Block/DoEndBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class DoEndBlock : Block +internal sealed class DoEndBlock : Block { private readonly List m_statements; diff --git a/src/UnluacNET/Decompile/Block/ElseEndBlock.cs b/src/UnluacNET/Decompile/Block/ElseEndBlock.cs index 3f7c2985..30929500 100644 --- a/src/UnluacNET/Decompile/Block/ElseEndBlock.cs +++ b/src/UnluacNET/Decompile/Block/ElseEndBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class ElseEndBlock : Block +internal sealed class ElseEndBlock : Block { private readonly List m_statements; diff --git a/src/UnluacNET/Decompile/Block/ForBlock.cs b/src/UnluacNET/Decompile/Block/ForBlock.cs index ff301a9b..95fb30a4 100644 --- a/src/UnluacNET/Decompile/Block/ForBlock.cs +++ b/src/UnluacNET/Decompile/Block/ForBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class ForBlock : Block +internal sealed class ForBlock : Block { private readonly int m_register; private readonly Registers m_r; diff --git a/src/UnluacNET/Decompile/Block/IfThenElseBlock.cs b/src/UnluacNET/Decompile/Block/IfThenElseBlock.cs index 1e6752f3..3489cd6f 100644 --- a/src/UnluacNET/Decompile/Block/IfThenElseBlock.cs +++ b/src/UnluacNET/Decompile/Block/IfThenElseBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class IfThenElseBlock : Block +internal sealed class IfThenElseBlock : Block { private readonly Branch m_branch; private readonly int m_loopback; diff --git a/src/UnluacNET/Decompile/Block/IfThenEndBlock.cs b/src/UnluacNET/Decompile/Block/IfThenEndBlock.cs index 62323cd6..65697399 100644 --- a/src/UnluacNET/Decompile/Block/IfThenEndBlock.cs +++ b/src/UnluacNET/Decompile/Block/IfThenEndBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class IfThenEndBlock : Block +internal sealed class IfThenEndBlock : Block { private readonly Branch m_branch; private readonly Stack m_stack; diff --git a/src/UnluacNET/Decompile/Block/OuterBlock.cs b/src/UnluacNET/Decompile/Block/OuterBlock.cs index 923c43a7..54aa6248 100644 --- a/src/UnluacNET/Decompile/Block/OuterBlock.cs +++ b/src/UnluacNET/Decompile/Block/OuterBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class OuterBlock : Block +internal sealed class OuterBlock : Block { private readonly List m_statements; diff --git a/src/UnluacNET/Decompile/Block/RepeatBlock.cs b/src/UnluacNET/Decompile/Block/RepeatBlock.cs index 7869ab7c..b05e3753 100644 --- a/src/UnluacNET/Decompile/Block/RepeatBlock.cs +++ b/src/UnluacNET/Decompile/Block/RepeatBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class RepeatBlock : Block +internal sealed class RepeatBlock : Block { private readonly Branch m_branch; private readonly Registers m_r; diff --git a/src/UnluacNET/Decompile/Block/SetBlock.cs b/src/UnluacNET/Decompile/Block/SetBlock.cs index b2286366..16170f8f 100644 --- a/src/UnluacNET/Decompile/Block/SetBlock.cs +++ b/src/UnluacNET/Decompile/Block/SetBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class SetBlock : Block +internal sealed class SetBlock : Block { private readonly bool m_empty; private readonly Registers m_r; diff --git a/src/UnluacNET/Decompile/Block/TForBlock.cs b/src/UnluacNET/Decompile/Block/TForBlock.cs index 5f6be09a..1c2eafe5 100644 --- a/src/UnluacNET/Decompile/Block/TForBlock.cs +++ b/src/UnluacNET/Decompile/Block/TForBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class TForBlock : Block +internal sealed class TForBlock : Block { private readonly int m_register; private readonly int m_length; diff --git a/src/UnluacNET/Decompile/Block/WhileBlock.cs b/src/UnluacNET/Decompile/Block/WhileBlock.cs index 031d2ed4..2e12d076 100644 --- a/src/UnluacNET/Decompile/Block/WhileBlock.cs +++ b/src/UnluacNET/Decompile/Block/WhileBlock.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class WhileBlock : Block +internal sealed class WhileBlock : Block { private readonly Branch m_branch; private readonly int m_loopback; diff --git a/src/UnluacNET/Decompile/Branch/AndBranch.cs b/src/UnluacNET/Decompile/Branch/AndBranch.cs index 2a54f831..50ed8408 100644 --- a/src/UnluacNET/Decompile/Branch/AndBranch.cs +++ b/src/UnluacNET/Decompile/Branch/AndBranch.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class AndBranch : Branch +internal sealed class AndBranch : Branch { private readonly Branch m_left; private readonly Branch m_right; diff --git a/src/UnluacNET/Decompile/Branch/AssignNode.cs b/src/UnluacNET/Decompile/Branch/AssignNode.cs index eea3b75b..f2545751 100644 --- a/src/UnluacNET/Decompile/Branch/AssignNode.cs +++ b/src/UnluacNET/Decompile/Branch/AssignNode.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class AssignNode : Branch +internal sealed class AssignNode : Branch { private Expression m_expression; diff --git a/src/UnluacNET/Decompile/Branch/EQNode.cs b/src/UnluacNET/Decompile/Branch/EQNode.cs index 3787d939..5d3e14f9 100644 --- a/src/UnluacNET/Decompile/Branch/EQNode.cs +++ b/src/UnluacNET/Decompile/Branch/EQNode.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class EQNode : Branch +internal sealed class EQNode : Branch { private readonly int m_left; private readonly int m_right; diff --git a/src/UnluacNET/Decompile/Branch/LENode.cs b/src/UnluacNET/Decompile/Branch/LENode.cs index 8943ef3f..6982e35f 100644 --- a/src/UnluacNET/Decompile/Branch/LENode.cs +++ b/src/UnluacNET/Decompile/Branch/LENode.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LENode : Branch +internal sealed class LENode : Branch { private readonly int m_left; private readonly int m_right; diff --git a/src/UnluacNET/Decompile/Branch/LTNode.cs b/src/UnluacNET/Decompile/Branch/LTNode.cs index f964b101..3399df08 100644 --- a/src/UnluacNET/Decompile/Branch/LTNode.cs +++ b/src/UnluacNET/Decompile/Branch/LTNode.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LTNode : Branch +internal sealed class LTNode : Branch { private readonly int m_left; private readonly int m_right; diff --git a/src/UnluacNET/Decompile/Branch/NotBranch.cs b/src/UnluacNET/Decompile/Branch/NotBranch.cs index 8b51c00d..06c0c395 100644 --- a/src/UnluacNET/Decompile/Branch/NotBranch.cs +++ b/src/UnluacNET/Decompile/Branch/NotBranch.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class NotBranch : Branch +internal sealed class NotBranch : Branch { private readonly Branch m_branch; diff --git a/src/UnluacNET/Decompile/Branch/OrBranch.cs b/src/UnluacNET/Decompile/Branch/OrBranch.cs index 448db074..171d687c 100644 --- a/src/UnluacNET/Decompile/Branch/OrBranch.cs +++ b/src/UnluacNET/Decompile/Branch/OrBranch.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class OrBranch : Branch +internal sealed class OrBranch : Branch { private readonly Branch m_left; private readonly Branch m_right; diff --git a/src/UnluacNET/Decompile/Branch/TestNode.cs b/src/UnluacNET/Decompile/Branch/TestNode.cs index 8276c4b5..d843b2fd 100644 --- a/src/UnluacNET/Decompile/Branch/TestNode.cs +++ b/src/UnluacNET/Decompile/Branch/TestNode.cs @@ -34,5 +34,5 @@ public override void UseExpression(Expression expression) } public override string ToString() - => string.Format("TestNode[test={0};inverted={1};line={2};begin={3};end={4}]", this.Test, this.Inverted, this.Line, this.Begin, this.End); + => $"TestNode[test={this.Test};inverted={this.Inverted};line={this.Line};begin={this.Begin};end={this.End}]"; } diff --git a/src/UnluacNET/Decompile/Branch/TestSetNode.cs b/src/UnluacNET/Decompile/Branch/TestSetNode.cs index dc55c2de..839244a2 100644 --- a/src/UnluacNET/Decompile/Branch/TestSetNode.cs +++ b/src/UnluacNET/Decompile/Branch/TestSetNode.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class TestSetNode : TestNode +internal sealed class TestSetNode : TestNode { public TestSetNode(int target, int test, bool inverted, int line, int begin, int end) : base(test, inverted, line, begin, end) diff --git a/src/UnluacNET/Decompile/Branch/TrueNode.cs b/src/UnluacNET/Decompile/Branch/TrueNode.cs index cf41708a..49a17f68 100644 --- a/src/UnluacNET/Decompile/Branch/TrueNode.cs +++ b/src/UnluacNET/Decompile/Branch/TrueNode.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class TrueNode : Branch +internal sealed class TrueNode : Branch { public TrueNode(int register, bool inverted, int line, int begin, int end) : base(line, begin, end) @@ -34,5 +34,5 @@ public override void UseExpression(Expression expression) } public override string ToString() - => string.Format("TrueNode[register={0};inverted={1};line={2};begin={3};end={4}]", this.Register, this.Inverted, this.Line, this.Begin, this.End); + => $"TrueNode[register={this.Register};inverted={this.Inverted};line={this.Line};begin={this.Begin};end={this.End}]"; } diff --git a/src/UnluacNET/Decompile/Code.cs b/src/UnluacNET/Decompile/Code.cs index 39daeb58..26b26c89 100644 --- a/src/UnluacNET/Decompile/Code.cs +++ b/src/UnluacNET/Decompile/Code.cs @@ -5,28 +5,28 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Code +internal sealed class Code { /* ** Size and position of opcode arguments */ - private static readonly int SIZE_C = 9; - private static readonly int SIZE_B = 9; - private static readonly int SIZE_Bx = SIZE_C + SIZE_B; - private static readonly int SIZE_A = 8; - private static readonly int SIZE_OP = 6; - private static readonly int POS_OP = 0; - private static readonly int POS_A = POS_OP + SIZE_OP; - private static readonly int POS_C = POS_A + SIZE_A; - private static readonly int POS_B = POS_C + SIZE_C; - private static readonly int POS_Bx = POS_C; + private const int SIZE_C = 9; + private const int SIZE_B = 9; + private const int SIZE_Bx = SIZE_C + SIZE_B; + private const int SIZE_A = 8; + private const int SIZE_OP = 6; + private const int POS_OP = 0; + private const int POS_A = POS_OP + SIZE_OP; + private const int POS_C = POS_A + SIZE_A; + private const int POS_B = POS_C + SIZE_C; + private const int POS_Bx = POS_C; /* ** Limits for opcode arguments ** (signed) int used to manipulate most arguments */ - private static readonly int MAXARG_Bx = (1 << SIZE_Bx) - 1; - private static readonly int MAXARG_sBx = MAXARG_Bx >> 1; + private const int MAXARG_Bx = (1 << SIZE_Bx) - 1; + private const int MAXARG_sBx = MAXARG_Bx >> 1; /* ** Macros to operate RK indices diff --git a/src/UnluacNET/Decompile/Constant.cs b/src/UnluacNET/Decompile/Constant.cs index 0be4c125..9222e869 100644 --- a/src/UnluacNET/Decompile/Constant.cs +++ b/src/UnluacNET/Decompile/Constant.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Constant +internal sealed class Constant { public const int CONST_NIL = 0; public const int CONST_BOOL = 1; @@ -178,8 +178,8 @@ public void Print(Output output) } } - if (unprinttable is 0 && !this.m_string.Contains("[[") && - (newLines > 1 || newLines is 1) && this.m_string.IndexOf('\n') != this.m_string.Length - 1) + if (unprinttable is 0 && !this.m_string.Contains("[[", StringComparison.Ordinal) && + (newLines > 1 || newLines is 1) && this.m_string.IndexOf('\n', StringComparison.Ordinal) != this.m_string.Length - 1) { var pipe = 0; var pipeString = new StringBuilder(); @@ -236,7 +236,7 @@ public void Print(Output output) } else { - var dec = cx.ToString(); + var dec = cx.ToString(CultureInfo.InvariantCulture); var len = dec.Length; output.Print("\\"); while (len++ < 3) diff --git a/src/UnluacNET/Decompile/Declaration.cs b/src/UnluacNET/Decompile/Declaration.cs index 7c59f411..b16e4a99 100644 --- a/src/UnluacNET/Decompile/Declaration.cs +++ b/src/UnluacNET/Decompile/Declaration.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Declaration +internal sealed class Declaration { public Declaration(LLocal local) { diff --git a/src/UnluacNET/Decompile/Decompiler.cs b/src/UnluacNET/Decompile/Decompiler.cs index 60d0c570..e625caaf 100644 --- a/src/UnluacNET/Decompile/Decompiler.cs +++ b/src/UnluacNET/Decompile/Decompiler.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Decompiler +internal sealed class Decompiler { private static Stack m_backup; private readonly int registers; @@ -16,7 +16,7 @@ internal class Decompiler private readonly int vararg; private readonly Op tForTarget; private Registers r; - private Block outer; + private OuterBlock outer; private List blocks; private bool[] skip; private bool[] reverseTarget; @@ -42,7 +42,7 @@ public Decompiler(LFunction function) this.DeclList = new Declaration[function.NumParams]; for (var i = 0; i < this.DeclList.Length; i++) { - var name = string.Format("_ARG_{0}_", i); + var name = $"_ARG_{i}_"; this.DeclList[i] = new Declaration(name, 0, this.length - 1); } } @@ -59,9 +59,9 @@ public Decompiler(LFunction function) public Declaration[] DeclList { get; private set; } // TODO: Pick better names - protected Function F { get; set; } + public Function F { get; set; } - protected LFunction Function { get; set; } + public LFunction Function { get; set; } public void Decompile() { diff --git a/src/UnluacNET/Decompile/Expression/BinaryExpression.cs b/src/UnluacNET/Decompile/Expression/BinaryExpression.cs index 25df9e06..81ff4b72 100644 --- a/src/UnluacNET/Decompile/Expression/BinaryExpression.cs +++ b/src/UnluacNET/Decompile/Expression/BinaryExpression.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class BinaryExpression : Expression +internal sealed class BinaryExpression : Expression { private readonly string m_op; private readonly Expression m_left; @@ -27,11 +27,11 @@ public override int ConstantIndex public override bool BeginsWithParen => this.LeftGroup || this.m_left.BeginsWithParen; - protected bool LeftGroup + public bool LeftGroup => this.Precedence > this.m_left.Precedence || (this.Precedence == this.m_left.Precedence && this.m_associativity == ASSOCIATIVITY_RIGHT); - protected bool RightGroup + public bool RightGroup => this.Precedence > this.m_right.Precedence || (this.Precedence == this.m_right.Precedence && this.m_associativity == ASSOCIATIVITY_LEFT); diff --git a/src/UnluacNET/Decompile/Expression/ClosureExpression.cs b/src/UnluacNET/Decompile/Expression/ClosureExpression.cs index ccf2fd4a..b9c7d812 100644 --- a/src/UnluacNET/Decompile/Expression/ClosureExpression.cs +++ b/src/UnluacNET/Decompile/Expression/ClosureExpression.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class ClosureExpression : Expression +internal sealed class ClosureExpression : Expression { private readonly LFunction m_function; private readonly int m_upvalueLine; @@ -47,7 +47,7 @@ public override void PrintClosure(Output output, Target name) { Decompiler d = new(this.m_function); output.Print("function "); - if (this.m_function.NumParams >= 1 && d.DeclList[0].Name.Equals("self") && + if (this.m_function.NumParams >= 1 && d.DeclList[0].Name.Equals("self", StringComparison.Ordinal) && name is TableTarget) { name.PrintMethod(output); diff --git a/src/UnluacNET/Decompile/Expression/ConstantExpression.cs b/src/UnluacNET/Decompile/Expression/ConstantExpression.cs index f757c611..0e242f9f 100644 --- a/src/UnluacNET/Decompile/Expression/ConstantExpression.cs +++ b/src/UnluacNET/Decompile/Expression/ConstantExpression.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class ConstantExpression : Expression +internal sealed class ConstantExpression : Expression { private readonly Constant m_constant; private readonly int m_index; diff --git a/src/UnluacNET/Decompile/Expression/Expression.cs b/src/UnluacNET/Decompile/Expression/Expression.cs index 83fa1c4c..fb6143ed 100644 --- a/src/UnluacNET/Decompile/Expression/Expression.cs +++ b/src/UnluacNET/Decompile/Expression/Expression.cs @@ -7,18 +7,18 @@ namespace Elskom.Generic.Libs.UnluacNET; internal abstract class Expression { - public static readonly int PRECEDENCE_OR = 1; - public static readonly int PRECEDENCE_AND = 2; - public static readonly int PRECEDENCE_COMPARE = 3; - public static readonly int PRECEDENCE_CONCAT = 4; - public static readonly int PRECEDENCE_ADD = 5; - public static readonly int PRECEDENCE_MUL = 6; - public static readonly int PRECEDENCE_UNARY = 7; - public static readonly int PRECEDENCE_POW = 8; - public static readonly int PRECEDENCE_ATOMIC = 9; - public static readonly int ASSOCIATIVITY_NONE = 0; - public static readonly int ASSOCIATIVITY_LEFT = 1; - public static readonly int ASSOCIATIVITY_RIGHT = 2; + public const int PRECEDENCE_OR = 1; + public const int PRECEDENCE_AND = 2; + public const int PRECEDENCE_COMPARE = 3; + public const int PRECEDENCE_CONCAT = 4; + public const int PRECEDENCE_ADD = 5; + public const int PRECEDENCE_MUL = 6; + public const int PRECEDENCE_UNARY = 7; + public const int PRECEDENCE_POW = 8; + public const int PRECEDENCE_ATOMIC = 9; + public const int ASSOCIATIVITY_NONE = 0; + public const int ASSOCIATIVITY_LEFT = 1; + public const int ASSOCIATIVITY_RIGHT = 2; public static readonly Expression NIL = new ConstantExpression(new(LNil.NIL), -1); protected Expression(int precedence) diff --git a/src/UnluacNET/Decompile/Expression/FunctionCall.cs b/src/UnluacNET/Decompile/Expression/FunctionCall.cs index 9d8c266d..85b9ad59 100644 --- a/src/UnluacNET/Decompile/Expression/FunctionCall.cs +++ b/src/UnluacNET/Decompile/Expression/FunctionCall.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class FunctionCall : Expression +internal sealed class FunctionCall : Expression { private readonly Expression m_function; private readonly Expression[] m_arguments; diff --git a/src/UnluacNET/Decompile/Expression/GlobalExpression.cs b/src/UnluacNET/Decompile/Expression/GlobalExpression.cs index e48febf6..f2c3dbfd 100644 --- a/src/UnluacNET/Decompile/Expression/GlobalExpression.cs +++ b/src/UnluacNET/Decompile/Expression/GlobalExpression.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class GlobalExpression : Expression +internal sealed class GlobalExpression : Expression { private readonly string m_name; private readonly int m_index; diff --git a/src/UnluacNET/Decompile/Expression/LocalVariable.cs b/src/UnluacNET/Decompile/Expression/LocalVariable.cs index d9549a8e..40a6a570 100644 --- a/src/UnluacNET/Decompile/Expression/LocalVariable.cs +++ b/src/UnluacNET/Decompile/Expression/LocalVariable.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LocalVariable : Expression +internal sealed class LocalVariable : Expression { public LocalVariable(Declaration decl) : base(PRECEDENCE_ATOMIC) diff --git a/src/UnluacNET/Decompile/Expression/TableLiteral.cs b/src/UnluacNET/Decompile/Expression/TableLiteral.cs index 64311640..14e7ab70 100644 --- a/src/UnluacNET/Decompile/Expression/TableLiteral.cs +++ b/src/UnluacNET/Decompile/Expression/TableLiteral.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class TableLiteral : Expression +internal sealed class TableLiteral : Expression { private readonly List m_entries; private readonly int m_capacity; @@ -180,6 +180,7 @@ public Entry(Expression key, Expression value, bool isList, int timestamp) public int CompareTo(Entry other) => this.Timestamp.CompareTo(other.Timestamp); + [SuppressMessage("Maintainability", "CA1508:Avoid dead conditional code", Justification = "False Positive.")] public override bool Equals(object obj) => ReferenceEquals(this, obj) && obj is not null && this.CompareTo((Entry)obj) == 0; diff --git a/src/UnluacNET/Decompile/Expression/TableReference.cs b/src/UnluacNET/Decompile/Expression/TableReference.cs index e76e3eee..22d84cb6 100644 --- a/src/UnluacNET/Decompile/Expression/TableReference.cs +++ b/src/UnluacNET/Decompile/Expression/TableReference.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class TableReference : Expression +internal sealed class TableReference : Expression { private readonly Expression m_table; private readonly Expression m_index; diff --git a/src/UnluacNET/Decompile/Expression/UnaryExpression.cs b/src/UnluacNET/Decompile/Expression/UnaryExpression.cs index ebb8f8e3..ddc599f6 100644 --- a/src/UnluacNET/Decompile/Expression/UnaryExpression.cs +++ b/src/UnluacNET/Decompile/Expression/UnaryExpression.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class UnaryExpression : Expression +internal sealed class UnaryExpression : Expression { private readonly string m_op; private readonly Expression m_expression; diff --git a/src/UnluacNET/Decompile/Expression/UpvalueExpression.cs b/src/UnluacNET/Decompile/Expression/UpvalueExpression.cs index afab714f..364c4cc8 100644 --- a/src/UnluacNET/Decompile/Expression/UpvalueExpression.cs +++ b/src/UnluacNET/Decompile/Expression/UpvalueExpression.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class UpvalueExpression : Expression +internal sealed class UpvalueExpression : Expression { private readonly string m_name; diff --git a/src/UnluacNET/Decompile/Expression/Vararg.cs b/src/UnluacNET/Decompile/Expression/Vararg.cs index 93e3f8b3..6fbffd0b 100644 --- a/src/UnluacNET/Decompile/Expression/Vararg.cs +++ b/src/UnluacNET/Decompile/Expression/Vararg.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Vararg : Expression +internal sealed class Vararg : Expression { private readonly bool m_multiple; diff --git a/src/UnluacNET/Decompile/Function.cs b/src/UnluacNET/Decompile/Function.cs index 97b3afee..ca1a2896 100644 --- a/src/UnluacNET/Decompile/Function.cs +++ b/src/UnluacNET/Decompile/Function.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Function +internal sealed class Function { private readonly Constant[] m_constants; diff --git a/src/UnluacNET/Decompile/OpcodeMap.cs b/src/UnluacNET/Decompile/OpcodeMap.cs index 16ab8c3b..745888cf 100644 --- a/src/UnluacNET/Decompile/OpcodeMap.cs +++ b/src/UnluacNET/Decompile/OpcodeMap.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class OpcodeMap +internal sealed class OpcodeMap { private readonly int[] luaP_opmodes = { diff --git a/src/UnluacNET/Decompile/Operation/CallOperation.cs b/src/UnluacNET/Decompile/Operation/CallOperation.cs index b9f0bbd7..4ee0bd71 100644 --- a/src/UnluacNET/Decompile/Operation/CallOperation.cs +++ b/src/UnluacNET/Decompile/Operation/CallOperation.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class CallOperation : Operation +internal sealed class CallOperation : Operation { private readonly FunctionCall m_call; diff --git a/src/UnluacNET/Decompile/Operation/GenericOperation.cs b/src/UnluacNET/Decompile/Operation/GenericOperation.cs index 1568453c..fd183353 100644 --- a/src/UnluacNET/Decompile/Operation/GenericOperation.cs +++ b/src/UnluacNET/Decompile/Operation/GenericOperation.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class GenericOperation : Operation +internal sealed class GenericOperation : Operation { private readonly Statement m_statement; diff --git a/src/UnluacNET/Decompile/Operation/GlobalSet.cs b/src/UnluacNET/Decompile/Operation/GlobalSet.cs index 8e873bba..7923d6ed 100644 --- a/src/UnluacNET/Decompile/Operation/GlobalSet.cs +++ b/src/UnluacNET/Decompile/Operation/GlobalSet.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class GlobalSet : Operation +internal sealed class GlobalSet : Operation { private readonly string m_global; private readonly Expression m_value; diff --git a/src/UnluacNET/Decompile/Operation/LambdaOperation.cs b/src/UnluacNET/Decompile/Operation/LambdaOperation.cs index 7065278e..3776d2a6 100644 --- a/src/UnluacNET/Decompile/Operation/LambdaOperation.cs +++ b/src/UnluacNET/Decompile/Operation/LambdaOperation.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LambdaOperation : Operation +internal sealed class LambdaOperation : Operation { private readonly Func m_func; diff --git a/src/UnluacNET/Decompile/Operation/RegisterSet.cs b/src/UnluacNET/Decompile/Operation/RegisterSet.cs index 558d73b9..60a234de 100644 --- a/src/UnluacNET/Decompile/Operation/RegisterSet.cs +++ b/src/UnluacNET/Decompile/Operation/RegisterSet.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class RegisterSet : Operation +internal sealed class RegisterSet : Operation { public RegisterSet(int line, int register, Expression value) : base(line) diff --git a/src/UnluacNET/Decompile/Operation/ReturnOperation.cs b/src/UnluacNET/Decompile/Operation/ReturnOperation.cs index 7411ed71..616c422e 100644 --- a/src/UnluacNET/Decompile/Operation/ReturnOperation.cs +++ b/src/UnluacNET/Decompile/Operation/ReturnOperation.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class ReturnOperation : Operation +internal sealed class ReturnOperation : Operation { private readonly Expression[] m_values; diff --git a/src/UnluacNET/Decompile/Operation/TableSet.cs b/src/UnluacNET/Decompile/Operation/TableSet.cs index c23dd617..453afc2f 100644 --- a/src/UnluacNET/Decompile/Operation/TableSet.cs +++ b/src/UnluacNET/Decompile/Operation/TableSet.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class TableSet : Operation +internal sealed class TableSet : Operation { private readonly Expression m_table; private readonly Expression m_index; diff --git a/src/UnluacNET/Decompile/Operation/UpvalueSet.cs b/src/UnluacNET/Decompile/Operation/UpvalueSet.cs index 5f2cef0a..f7f3e681 100644 --- a/src/UnluacNET/Decompile/Operation/UpvalueSet.cs +++ b/src/UnluacNET/Decompile/Operation/UpvalueSet.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class UpvalueSet : Operation +internal sealed class UpvalueSet : Operation { private readonly UpvalueTarget m_target; private readonly Expression m_value; diff --git a/src/UnluacNET/Decompile/Output.cs b/src/UnluacNET/Decompile/Output.cs index 21850fff..25be411b 100644 --- a/src/UnluacNET/Decompile/Output.cs +++ b/src/UnluacNET/Decompile/Output.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Output +internal sealed class Output { private readonly TextWriter m_writer; diff --git a/src/UnluacNET/Decompile/Registers.cs b/src/UnluacNET/Decompile/Registers.cs index 6bfb482f..eb208370 100644 --- a/src/UnluacNET/Decompile/Registers.cs +++ b/src/UnluacNET/Decompile/Registers.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Registers +internal sealed class Registers { private readonly Declaration[,] m_decls; private readonly Function m_func; diff --git a/src/UnluacNET/Decompile/Statement/Assignment.cs b/src/UnluacNET/Decompile/Statement/Assignment.cs index 52183edb..978ced91 100644 --- a/src/UnluacNET/Decompile/Statement/Assignment.cs +++ b/src/UnluacNET/Decompile/Statement/Assignment.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Assignment : Statement +internal sealed class Assignment : Statement { private readonly List m_targets = new(5); private readonly List m_values = new(5); diff --git a/src/UnluacNET/Decompile/Statement/Declare.cs b/src/UnluacNET/Decompile/Statement/Declare.cs index 5a8c193e..c97fc3fa 100644 --- a/src/UnluacNET/Decompile/Statement/Declare.cs +++ b/src/UnluacNET/Decompile/Statement/Declare.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Declare : Statement +internal sealed class Declare : Statement { private readonly List m_decls; diff --git a/src/UnluacNET/Decompile/Statement/FunctionCallStatement.cs b/src/UnluacNET/Decompile/Statement/FunctionCallStatement.cs index 932c3b6f..60e1cec9 100644 --- a/src/UnluacNET/Decompile/Statement/FunctionCallStatement.cs +++ b/src/UnluacNET/Decompile/Statement/FunctionCallStatement.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class FunctionCallStatement : Statement +internal sealed class FunctionCallStatement : Statement { private readonly FunctionCall m_call; diff --git a/src/UnluacNET/Decompile/Statement/Return.cs b/src/UnluacNET/Decompile/Statement/Return.cs index f8ff9dde..6f61e761 100644 --- a/src/UnluacNET/Decompile/Statement/Return.cs +++ b/src/UnluacNET/Decompile/Statement/Return.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Return : Statement +internal sealed class Return : Statement { private readonly Expression[] values; diff --git a/src/UnluacNET/Decompile/Target/GlobalTarget.cs b/src/UnluacNET/Decompile/Target/GlobalTarget.cs index a945fec7..ab23ed79 100644 --- a/src/UnluacNET/Decompile/Target/GlobalTarget.cs +++ b/src/UnluacNET/Decompile/Target/GlobalTarget.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class GlobalTarget : Target +internal sealed class GlobalTarget : Target { private readonly string m_name; diff --git a/src/UnluacNET/Decompile/Target/TableTarget.cs b/src/UnluacNET/Decompile/Target/TableTarget.cs index b1b6086c..7746839d 100644 --- a/src/UnluacNET/Decompile/Target/TableTarget.cs +++ b/src/UnluacNET/Decompile/Target/TableTarget.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class TableTarget : Target +internal sealed class TableTarget : Target { private readonly Expression m_table; private readonly Expression m_index; diff --git a/src/UnluacNET/Decompile/Target/UpvalueTarget.cs b/src/UnluacNET/Decompile/Target/UpvalueTarget.cs index ce536675..21c51c4a 100644 --- a/src/UnluacNET/Decompile/Target/UpvalueTarget.cs +++ b/src/UnluacNET/Decompile/Target/UpvalueTarget.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class UpvalueTarget : Target +internal sealed class UpvalueTarget : Target { private readonly string m_name; diff --git a/src/UnluacNET/Decompile/Target/VariableTarget.cs b/src/UnluacNET/Decompile/Target/VariableTarget.cs index 73f292fb..808ecbe7 100644 --- a/src/UnluacNET/Decompile/Target/VariableTarget.cs +++ b/src/UnluacNET/Decompile/Target/VariableTarget.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class VariableTarget : Target +internal sealed class VariableTarget : Target { public VariableTarget(Declaration decl) => this.Declaration = decl; diff --git a/src/UnluacNET/Decompile/Upvalues.cs b/src/UnluacNET/Decompile/Upvalues.cs index c7d9af52..900df756 100644 --- a/src/UnluacNET/Decompile/Upvalues.cs +++ b/src/UnluacNET/Decompile/Upvalues.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Upvalues +internal sealed class Upvalues { private readonly LUpvalue[] m_upvalues; @@ -15,7 +15,7 @@ public Upvalues(LUpvalue[] upvalues) public string GetName(int idx) => idx < this.m_upvalues.Length && this.m_upvalues[idx].Name != null ? this.m_upvalues[idx].Name - : string.Format("_UPVALUE{0}_", idx); + : $"_UPVALUE{idx}_"; public UpvalueExpression GetExpression(int index) => new(this.GetName(index)); diff --git a/src/UnluacNET/Directory.Build.targets b/src/UnluacNET/Directory.Build.targets index 99c13ec5..17bc3795 100644 --- a/src/UnluacNET/Directory.Build.targets +++ b/src/UnluacNET/Directory.Build.targets @@ -8,6 +8,8 @@ stylecop.json + + diff --git a/src/UnluacNET/Parse/BHeader.cs b/src/UnluacNET/Parse/BHeader.cs index a44a02f2..33b8d752 100644 --- a/src/UnluacNET/Parse/BHeader.cs +++ b/src/UnluacNET/Parse/BHeader.cs @@ -5,9 +5,9 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class BHeader +internal sealed class BHeader { - private static readonly int Signature = 0x61754C1B; // '\x1B\Lua' + private const int Signature = 0x61754C1B; // '\x1B\Lua' public BHeader(Stream stream) { diff --git a/src/UnluacNET/Parse/BInteger.cs b/src/UnluacNET/Parse/BInteger.cs index 58609c85..28c7a0ed 100644 --- a/src/UnluacNET/Parse/BInteger.cs +++ b/src/UnluacNET/Parse/BInteger.cs @@ -7,8 +7,8 @@ namespace Elskom.Generic.Libs.UnluacNET; internal class BInteger : IBObject { - private static readonly long MAX_INT = int.MaxValue; - private static readonly long MIN_INT = int.MinValue; + private const long MAX_INT = int.MaxValue; + private const long MIN_INT = int.MinValue; // TODO: Why not just use a 'long' to hold both sizes? Doesn't make much of a difference IMO private readonly long m_big; diff --git a/src/UnluacNET/Parse/BIntegerType.cs b/src/UnluacNET/Parse/BIntegerType.cs index 3c77b71c..983df86a 100644 --- a/src/UnluacNET/Parse/BIntegerType.cs +++ b/src/UnluacNET/Parse/BIntegerType.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class BIntegerType : BObjectType +internal sealed class BIntegerType : BObjectType { public BIntegerType(int intSize) => this.IntSize = intSize; @@ -23,7 +23,7 @@ public override BInteger Parse(Stream stream, BHeader header) return value; } - protected internal BInteger RawParse(Stream stream, BHeader header) + internal BInteger RawParse(Stream stream, BHeader header) { // HACK HACK HACK var bigEndian = header.BigEndian; diff --git a/src/UnluacNET/Parse/BList.cs b/src/UnluacNET/Parse/BList.cs index 5b12415c..9d8650dd 100644 --- a/src/UnluacNET/Parse/BList.cs +++ b/src/UnluacNET/Parse/BList.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class BList : IBObject +internal sealed class BList : IBObject where T : IBObject { private readonly List m_values; diff --git a/src/UnluacNET/Parse/BSizeT.cs b/src/UnluacNET/Parse/BSizeT.cs index 08b659b3..46537817 100644 --- a/src/UnluacNET/Parse/BSizeT.cs +++ b/src/UnluacNET/Parse/BSizeT.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class BSizeT : BInteger +internal sealed class BSizeT : BInteger { public BSizeT(BInteger b) : base(b) diff --git a/src/UnluacNET/Parse/BSizeTType.cs b/src/UnluacNET/Parse/BSizeTType.cs index 1bcf91dc..c83c07db 100644 --- a/src/UnluacNET/Parse/BSizeTType.cs +++ b/src/UnluacNET/Parse/BSizeTType.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class BSizeTType : BObjectType +internal sealed class BSizeTType : BObjectType { private readonly BIntegerType integerType; diff --git a/src/UnluacNET/Parse/LBoolean.cs b/src/UnluacNET/Parse/LBoolean.cs index e7ccc0dc..a8c76f91 100644 --- a/src/UnluacNET/Parse/LBoolean.cs +++ b/src/UnluacNET/Parse/LBoolean.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LBoolean : LObject +internal sealed class LBoolean : LObject { public static readonly LBoolean LTRUE = new() { Value = true, }; public static readonly LBoolean LFALSE = new() { Value = false, }; diff --git a/src/UnluacNET/Parse/LBooleanType.cs b/src/UnluacNET/Parse/LBooleanType.cs index 2c58d319..2e267130 100644 --- a/src/UnluacNET/Parse/LBooleanType.cs +++ b/src/UnluacNET/Parse/LBooleanType.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LBooleanType : BObjectType +internal sealed class LBooleanType : BObjectType { public override LBoolean Parse(Stream stream, BHeader header) { diff --git a/src/UnluacNET/Parse/LConstantType.cs b/src/UnluacNET/Parse/LConstantType.cs index 1c12ae92..796f550d 100644 --- a/src/UnluacNET/Parse/LConstantType.cs +++ b/src/UnluacNET/Parse/LConstantType.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LConstantType : BObjectType +internal sealed class LConstantType : BObjectType { public override LObject Parse(Stream stream, BHeader header) { diff --git a/src/UnluacNET/Parse/LDoubleNumber.cs b/src/UnluacNET/Parse/LDoubleNumber.cs index 36579b36..af07ef2d 100644 --- a/src/UnluacNET/Parse/LDoubleNumber.cs +++ b/src/UnluacNET/Parse/LDoubleNumber.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LDoubleNumber : LNumber +internal sealed class LDoubleNumber : LNumber { public LDoubleNumber(double number) => this.Number = number; @@ -21,5 +21,7 @@ public override int GetHashCode() => throw new NotImplementedException(); public override string ToString() - => this.Number == Math.Round(this.Number) ? ((long)this.Number).ToString() : this.Number.ToString(); + => this.Number == Math.Round(this.Number) + ? ((long)this.Number).ToString(CultureInfo.InvariantCulture) + : this.Number.ToString(CultureInfo.InvariantCulture); } diff --git a/src/UnluacNET/Parse/LFloatNumber.cs b/src/UnluacNET/Parse/LFloatNumber.cs index 551fa4f8..ef3b365b 100644 --- a/src/UnluacNET/Parse/LFloatNumber.cs +++ b/src/UnluacNET/Parse/LFloatNumber.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LFloatNumber : LNumber +internal sealed class LFloatNumber : LNumber { public LFloatNumber(float number) => this.Number = number; @@ -21,5 +21,7 @@ public override int GetHashCode() => throw new NotImplementedException(); public override string ToString() - => this.Number == (float)Math.Round(this.Number) ? ((int)this.Number).ToString() : this.Number.ToString(); + => this.Number == (float)Math.Round(this.Number) + ? ((int)this.Number).ToString(CultureInfo.InvariantCulture) + : this.Number.ToString(CultureInfo.InvariantCulture); } diff --git a/src/UnluacNET/Parse/LFunction.cs b/src/UnluacNET/Parse/LFunction.cs index e3bbf700..c7f2ffa1 100644 --- a/src/UnluacNET/Parse/LFunction.cs +++ b/src/UnluacNET/Parse/LFunction.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LFunction : IBObject +internal sealed class LFunction : IBObject { public LFunction(BHeader header, int[] code, LLocal[] locals, LObject[] constants, LUpvalue[] upvalues, LFunction[] functions, int maximumStackSize, int numUpValues, int numParams, int vararg) { diff --git a/src/UnluacNET/Parse/LFunctionType52.cs b/src/UnluacNET/Parse/LFunctionType52.cs index a5628550..41092d5c 100644 --- a/src/UnluacNET/Parse/LFunctionType52.cs +++ b/src/UnluacNET/Parse/LFunctionType52.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LFunctionType52 : LFunctionType +internal sealed class LFunctionType52 : LFunctionType { protected override void ParseDebug(Stream stream, BHeader header, LFunctionParseState s) { diff --git a/src/UnluacNET/Parse/LIntNumber.cs b/src/UnluacNET/Parse/LIntNumber.cs index 0f66fd5e..f8ba34e0 100644 --- a/src/UnluacNET/Parse/LIntNumber.cs +++ b/src/UnluacNET/Parse/LIntNumber.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LIntNumber : LNumber +internal sealed class LIntNumber : LNumber { public LIntNumber(int number) => this.Number = number; @@ -21,5 +21,5 @@ public override int GetHashCode() => throw new NotImplementedException(); public override string ToString() - => this.Number.ToString(); + => this.Number.ToString(CultureInfo.InvariantCulture); } diff --git a/src/UnluacNET/Parse/LLocal.cs b/src/UnluacNET/Parse/LLocal.cs index e6e36efe..a86e7152 100644 --- a/src/UnluacNET/Parse/LLocal.cs +++ b/src/UnluacNET/Parse/LLocal.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LLocal : IBObject +internal sealed class LLocal : IBObject { public LLocal(LString name, BInteger start, BInteger end) { diff --git a/src/UnluacNET/Parse/LLocalType.cs b/src/UnluacNET/Parse/LLocalType.cs index 3b0e052b..eafd30c9 100644 --- a/src/UnluacNET/Parse/LLocalType.cs +++ b/src/UnluacNET/Parse/LLocalType.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LLocalType : BObjectType +internal sealed class LLocalType : BObjectType { public override LLocal Parse(Stream stream, BHeader header) { diff --git a/src/UnluacNET/Parse/LLongNumber.cs b/src/UnluacNET/Parse/LLongNumber.cs index 77c45ca0..3722f72b 100644 --- a/src/UnluacNET/Parse/LLongNumber.cs +++ b/src/UnluacNET/Parse/LLongNumber.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LLongNumber : LNumber +internal sealed class LLongNumber : LNumber { public LLongNumber(long number) => this.Number = number; @@ -21,5 +21,5 @@ public override int GetHashCode() => throw new NotImplementedException(); public override string ToString() - => this.Number.ToString(); + => this.Number.ToString(CultureInfo.InvariantCulture); } diff --git a/src/UnluacNET/Parse/LNil.cs b/src/UnluacNET/Parse/LNil.cs index 121bc278..fe21ec5b 100644 --- a/src/UnluacNET/Parse/LNil.cs +++ b/src/UnluacNET/Parse/LNil.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LNil : LObject +internal sealed class LNil : LObject { public static readonly LNil NIL = new(); diff --git a/src/UnluacNET/Parse/LNumberType.cs b/src/UnluacNET/Parse/LNumberType.cs index 67bb227f..160288ee 100644 --- a/src/UnluacNET/Parse/LNumberType.cs +++ b/src/UnluacNET/Parse/LNumberType.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LNumberType : BObjectType +internal sealed class LNumberType : BObjectType { public LNumberType(int size, bool integral) { diff --git a/src/UnluacNET/Parse/LSourceLines.cs b/src/UnluacNET/Parse/LSourceLines.cs index 2b49a9d0..8d940a1d 100644 --- a/src/UnluacNET/Parse/LSourceLines.cs +++ b/src/UnluacNET/Parse/LSourceLines.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LSourceLines +internal sealed class LSourceLines { // TODO: Encapsulate a LuaStream of some sort to automatically support Big-Endian public static LSourceLines Parse(Stream stream) diff --git a/src/UnluacNET/Parse/LString.cs b/src/UnluacNET/Parse/LString.cs index 2471ff4e..9a387788 100644 --- a/src/UnluacNET/Parse/LString.cs +++ b/src/UnluacNET/Parse/LString.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LString : LObject +internal sealed class LString : LObject { public LString(BSizeT size, string value) { diff --git a/src/UnluacNET/Parse/LStringType.cs b/src/UnluacNET/Parse/LStringType.cs index 99a5d2b0..9dfe93ce 100644 --- a/src/UnluacNET/Parse/LStringType.cs +++ b/src/UnluacNET/Parse/LStringType.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LStringType : BObjectType +internal sealed class LStringType : BObjectType { public override LString Parse(Stream stream, BHeader header) { diff --git a/src/UnluacNET/Parse/LUpvalue.cs b/src/UnluacNET/Parse/LUpvalue.cs index 5f193933..351a3594 100644 --- a/src/UnluacNET/Parse/LUpvalue.cs +++ b/src/UnluacNET/Parse/LUpvalue.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LUpvalue : IBObject +internal sealed class LUpvalue : IBObject { public int Index { get; set; } diff --git a/src/UnluacNET/Parse/LUpvalueType.cs b/src/UnluacNET/Parse/LUpvalueType.cs index 6941e5fd..8166b418 100644 --- a/src/UnluacNET/Parse/LUpvalueType.cs +++ b/src/UnluacNET/Parse/LUpvalueType.cs @@ -5,7 +5,7 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class LUpvalueType : BObjectType +internal sealed class LUpvalueType : BObjectType { public override LUpvalue Parse(Stream stream, BHeader header) => new() diff --git a/src/UnluacNET/Version.cs b/src/UnluacNET/Version.cs index d8a954a5..ebb2e1a4 100644 --- a/src/UnluacNET/Version.cs +++ b/src/UnluacNET/Version.cs @@ -5,13 +5,13 @@ namespace Elskom.Generic.Libs.UnluacNET; -internal class Version +internal sealed class Version { public static readonly Version LUA51 = new(0x51); public static readonly Version LUA52 = new(0x52); private readonly int versionNumber; - protected Version(int versionNumber) + public Version(int versionNumber) { this.versionNumber = versionNumber; this.HasHeaderTail = this.versionNumber is not 0x51; diff --git a/src/ZipAssembly/.editorconfig b/src/ZipAssembly/.editorconfig index a01d0fb9..877dbcf8 100644 --- a/src/ZipAssembly/.editorconfig +++ b/src/ZipAssembly/.editorconfig @@ -152,3 +152,6 @@ dotnet_diagnostic.S3925.severity = none # S3903: Move '%s' into a named namespace. dotnet_diagnostic.S3903.severity = none + +# S1133: Do not forget to remove this deprecated code someday. +dotnet_diagnostic.S1133.severity = suggestion diff --git a/src/ZipAssembly/Directory.Build.targets b/src/ZipAssembly/Directory.Build.targets index f84f3178..f747ed60 100644 --- a/src/ZipAssembly/Directory.Build.targets +++ b/src/ZipAssembly/Directory.Build.targets @@ -6,11 +6,14 @@ stylecop.json + + + diff --git a/src/ZipAssembly/Properties/Resources.resx b/src/ZipAssembly/Properties/Resources.resx index 7ba20e6e..f7b935d2 100644 --- a/src/ZipAssembly/Properties/Resources.resx +++ b/src/ZipAssembly/Properties/Resources.resx @@ -1,33 +1,129 @@ - - - - - - - - text/microsoft-resx - - - 1.3 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - {0} is not allowed to be empty. - - - {0} does not exist. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + {0} does not exist. + + + {0} must end with '.dll' to be a valid assembly name. + + + Assembly specified to load in ZipFile not found. + \ No newline at end of file diff --git a/src/ZipAssembly/ZipAssembly/ZipAssembly.cs b/src/ZipAssembly/ZipAssembly/ZipAssembly.cs index a1ffd198..ec427a27 100644 --- a/src/ZipAssembly/ZipAssembly/ZipAssembly.cs +++ b/src/ZipAssembly/ZipAssembly/ZipAssembly.cs @@ -11,6 +11,9 @@ namespace Elskom.Generic.Libs; [Serializable] public sealed class ZipAssembly : Assembly { + private static readonly CompositeFormat ZipAssemblyDoesNotExist = CompositeFormat.Parse(Resources.ZipAssembly_does_not_exist); + private static readonly CompositeFormat ZipAssemblyMustEndWithDll = CompositeFormat.Parse(Resources.ZipAssembly_must_end_with_dll); + // always set to Zip file full path + \\ + file path in zip. private string locationValue; @@ -22,7 +25,8 @@ private ZipAssembly(SerializationInfo serializationInfo, StreamingContext stream /// /// Gets the location of the assembly in the zip file. /// - public override string Location => this.locationValue; + public override string Location + => this.locationValue; /// /// Loads the assembly with it’s debugging symbols @@ -32,8 +36,11 @@ private ZipAssembly(SerializationInfo serializationInfo, StreamingContext stream /// The assembly file name to load. /// The context to load the assemblies into. /// A new that represents the loaded assembly. + /// + /// When the passed in or the passed in is . + /// /// - /// When is null, Empty, or does not exist. + /// When Empty, or does not exist. /// Or is null, Empty or does not end with the '.dll' extension. /// /// @@ -45,25 +52,18 @@ private ZipAssembly(SerializationInfo serializationInfo, StreamingContext stream /// public static ZipAssembly? LoadFromZip(string zipFileName, string assemblyName, AssemblyLoadContext context) { - if (string.IsNullOrWhiteSpace(zipFileName)) - { - throw new ArgumentException(string.Format(Resources.ZipAssembly_not_allowed_to_be_empty!, nameof(zipFileName)), nameof(zipFileName)); - } - + ArgumentNullException.ThrowIfNull(context); + ArgumentException.ThrowIfNullOrEmpty(zipFileName); + ArgumentException.ThrowIfNullOrEmpty(assemblyName); if (!File.Exists(zipFileName)) { - throw new ArgumentException(string.Format(Resources.ZipAssembly_does_not_exist!, nameof(zipFileName)), nameof(zipFileName)); - } - - if (string.IsNullOrWhiteSpace(assemblyName)) - { - throw new ArgumentException(string.Format(Resources.ZipAssembly_not_allowed_to_be_empty!, nameof(assemblyName)), nameof(assemblyName)); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ZipAssemblyDoesNotExist!, nameof(zipFileName)), nameof(zipFileName)); } if (!assemblyName.EndsWith(".dll", StringComparison.Ordinal)) { // setting pdbFileName fails or makes unpredicted/unwanted things if this is not checked - throw new ArgumentException(string.Format(Resources.ZipAssembly_must_end_with_dll!, nameof(assemblyName)), nameof(assemblyName)); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ZipAssemblyMustEndWithDll!, nameof(assemblyName)), nameof(assemblyName)); } // check if the assembly is in the zip file. @@ -80,7 +80,7 @@ private ZipAssembly(SerializationInfo serializationInfo, StreamingContext stream GetBytesFromZipFile(assemblyName, zipFile, out asmbytes, out found, out zipAssemblyName); if (Debugger.IsAttached) { - var pdbFileName = assemblyName.Replace("dll", "pdb"); + var pdbFileName = assemblyName.Replace("dll", "pdb", StringComparison.OrdinalIgnoreCase); GetBytesFromZipFile(pdbFileName, zipFile, out pdbbytes, out _, out pdbAssemblyName); } } diff --git a/src/ZipAssembly/ZipAssembly/ZipAssemblyLoadException.cs b/src/ZipAssembly/ZipAssembly/ZipAssemblyLoadException.cs index 22bc246a..addc1ead 100644 --- a/src/ZipAssembly/ZipAssembly/ZipAssemblyLoadException.cs +++ b/src/ZipAssembly/ZipAssembly/ZipAssemblyLoadException.cs @@ -65,6 +65,8 @@ public ZipAssemblyLoadException(string message, Exception innerException) /// /// The class name is or is zero (0). /// + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.", DiagnosticId = "SYSLIB0051", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] protected ZipAssemblyLoadException(SerializationInfo info, StreamingContext context) : base(info, context) {