From d116903892668ea51a23aa18d472019a68381861 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Sat, 15 Jan 2022 12:39:06 -0700 Subject: [PATCH] Add some "unchecked" blocks Try to identify places where integer overflow is expected and mark them as "unchecked" --- src/LibHac/Common/Keys/ExternalKeyReader.cs | 4 +- src/LibHac/Common/U8StringBuilder.cs | 2 +- src/LibHac/Crypto/Impl/AesCtrModeNi.cs | 6 +-- src/LibHac/Crypto/Impl/AesXtsMode.cs | 13 +++--- src/LibHac/FsSrv/SaveDataFileSystemService.cs | 2 +- src/LibHac/Result.cs | 12 +++--- .../Tools/FsSystem/Aes128XtsTransform.cs | 4 +- src/LibHac/Util/Impl/HexConverter.cs | 41 +++++++++++-------- src/LibHac/Util/StringUtils.cs | 8 ++-- 9 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/LibHac/Common/Keys/ExternalKeyReader.cs b/src/LibHac/Common/Keys/ExternalKeyReader.cs index cf641250..d3e30dcb 100644 --- a/src/LibHac/Common/Keys/ExternalKeyReader.cs +++ b/src/LibHac/Common/Keys/ExternalKeyReader.cs @@ -566,7 +566,7 @@ public static class ExternalKeyReader [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool IsValidNameChar(char c) { - return (c | 0x20u) - 'a' <= 'z' - 'a' || (uint)(c - '0') <= 9 || c == '_'; + return unchecked((c | 0x20u) - 'a' <= 'z' - 'a' || (uint)(c - '0') <= 9 || c == '_'); } private static bool TryGetKeyInfo(out SpecificKeyInfo info, List keyList, ReadOnlySpan keyName) @@ -584,4 +584,4 @@ public static class ExternalKeyReader return false; } -} +} \ No newline at end of file diff --git a/src/LibHac/Common/U8StringBuilder.cs b/src/LibHac/Common/U8StringBuilder.cs index 73b8bd23..e07b9914 100644 --- a/src/LibHac/Common/U8StringBuilder.cs +++ b/src/LibHac/Common/U8StringBuilder.cs @@ -147,7 +147,7 @@ public ref struct U8StringBuilder // Remove possible sign extension if needed if (mask == 'x' || mask == 'X') { - value &= (long)mask; + value &= unchecked((long)mask); } int bytesWritten; diff --git a/src/LibHac/Crypto/Impl/AesCtrModeNi.cs b/src/LibHac/Crypto/Impl/AesCtrModeNi.cs index 87f0a0f2..492fd230 100644 --- a/src/LibHac/Crypto/Impl/AesCtrModeNi.cs +++ b/src/LibHac/Crypto/Impl/AesCtrModeNi.cs @@ -31,8 +31,8 @@ public struct AesCtrModeNi ref Vector128 inBlock = ref Unsafe.As>(ref MemoryMarshal.GetReference(input)); ref Vector128 outBlock = ref Unsafe.As>(ref MemoryMarshal.GetReference(output)); - Vector128 byteSwapMask = Vector128.Create((ulong)0x706050403020100, 0x8090A0B0C0D0E0F).AsByte(); - var inc = Vector128.Create((ulong)0, 1); + Vector128 byteSwapMask = Vector128.Create(0x706050403020100ul, 0x8090A0B0C0D0E0Ful).AsByte(); + var inc = Vector128.Create(0ul, 1ul); Vector128 iv = Iv; Vector128 bSwappedIv = Ssse3.Shuffle(iv, byteSwapMask).AsUInt64(); @@ -122,4 +122,4 @@ public struct AesCtrModeNi Unsafe.ReadUnaligned>(ref counter[0]); } -} +} \ No newline at end of file diff --git a/src/LibHac/Crypto/Impl/AesXtsMode.cs b/src/LibHac/Crypto/Impl/AesXtsMode.cs index af446541..2fafd67e 100644 --- a/src/LibHac/Crypto/Impl/AesXtsMode.cs +++ b/src/LibHac/Crypto/Impl/AesXtsMode.cs @@ -155,12 +155,15 @@ public struct AesXtsMode [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Gf128Mul(ref Buffer16 buffer) { - Span b = buffer.AsSpan(); + unchecked + { + Span b = buffer.AsSpan(); - ulong tt = (ulong)((long)b[1] >> 63) & 0x87; + ulong tt = (ulong)((long)b[1] >> 63) & 0x87; - b[1] = (b[1] << 1) | (b[0] >> 63); - b[0] = (b[0] << 1) ^ tt; + b[1] = (b[1] << 1) | (b[0] >> 63); + b[0] = (b[0] << 1) ^ tt; + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -173,4 +176,4 @@ public struct AesXtsMode outputS[0] = input1S[0] ^ input2S[0]; outputS[1] = input1S[1] ^ input2S[1]; } -} +} \ No newline at end of file diff --git a/src/LibHac/FsSrv/SaveDataFileSystemService.cs b/src/LibHac/FsSrv/SaveDataFileSystemService.cs index 23955958..b1ed8f95 100644 --- a/src/LibHac/FsSrv/SaveDataFileSystemService.cs +++ b/src/LibHac/FsSrv/SaveDataFileSystemService.cs @@ -2166,7 +2166,7 @@ internal class SaveDataFileSystemService : ISaveDataTransferCoreInterface, ISave private bool IsStaticSaveDataIdValueRange(ulong id) { - return (long)id < 0; + return unchecked((long)id) < 0; } private void ModifySaveDataExtraData(ref SaveDataExtraData currentExtraData, in SaveDataExtraData extraData, diff --git a/src/LibHac/Result.cs b/src/LibHac/Result.cs index c096ed4b..08affaac 100644 --- a/src/LibHac/Result.cs +++ b/src/LibHac/Result.cs @@ -289,7 +289,9 @@ public readonly struct Result : IEquatable /// The representing the start of this result range. /// If returning a from a function, use instead. /// - public Result Value => new Result((BaseType)_value); + // The conversion to int won't remove the part of the value containing the description end, but that doesn't + // matter because the constructor for Result will take care of that. + public Result Value => new Result(unchecked((BaseType)_value)); /// /// Checks if the range of this includes the provided . @@ -307,7 +309,7 @@ public readonly struct Result : IEquatable } return result.Module == Module && - result.Description - DescriptionRangeStart <= DescriptionRangeEnd - DescriptionRangeStart; + unchecked(result.Description - DescriptionRangeStart <= DescriptionRangeEnd - DescriptionRangeStart); } /// @@ -356,7 +358,7 @@ public readonly struct Result : IEquatable [MethodImpl(MethodImplOptions.AggressiveInlining)] private static BaseType GetBitsValueLong(ulong value, int bitsOffset, int bitsCount) { - return (BaseType)(value >> bitsOffset) & ~(~default(BaseType) << bitsCount); + return unchecked((BaseType)(value >> bitsOffset)) & ~(~default(BaseType) << bitsCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -391,7 +393,7 @@ public readonly struct Result : IEquatable public BaseType DescriptionRangeStart => GetBitsValueLong(_value, DescriptionBitsOffset, DescriptionBitsCount); public BaseType DescriptionRangeEnd => GetBitsValueLong(_value, DescriptionEndBitsOffset, DescriptionBitsCount); - private Result Value => new Result((BaseType)_value); + private Result Value => new Result(unchecked((BaseType)_value)); /// /// Checks if the range of this includes the provided . @@ -409,7 +411,7 @@ public readonly struct Result : IEquatable } return result.Module == Module && - result.Description - DescriptionRangeStart <= DescriptionRangeEnd - DescriptionRangeStart; + unchecked(result.Description - DescriptionRangeStart <= DescriptionRangeEnd - DescriptionRangeStart); } } } diff --git a/src/LibHac/Tools/FsSystem/Aes128XtsTransform.cs b/src/LibHac/Tools/FsSystem/Aes128XtsTransform.cs index 2edccd25..6c7ccfbe 100644 --- a/src/LibHac/Tools/FsSystem/Aes128XtsTransform.cs +++ b/src/LibHac/Tools/FsSystem/Aes128XtsTransform.cs @@ -174,7 +174,7 @@ public class Aes128XtsTransform for (int i = 2; i < bufL.Length; i += 2) { - ulong tt = (ulong)((long)a >> 63) & 0x87; + ulong tt = unchecked((ulong)((long)a >> 63) & 0x87); a = (a << 1) | (b >> 63); b = (b << 1) ^ tt; @@ -193,7 +193,7 @@ public class Aes128XtsTransform { for (int i = 0xF; i >= 0; i--) { - value[i] = (byte)sector; + value[i] = unchecked((byte)sector); sector >>= 8; } } diff --git a/src/LibHac/Util/Impl/HexConverter.cs b/src/LibHac/Util/Impl/HexConverter.cs index e7bd9471..a0d4e230 100644 --- a/src/LibHac/Util/Impl/HexConverter.cs +++ b/src/LibHac/Util/Impl/HexConverter.cs @@ -64,21 +64,27 @@ internal static class HexConverter [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ToBytesBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) { - uint difference = ((value & 0xF0U) << 4) + (value & 0x0FU) - 0x8989U; - uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; + unchecked + { + uint difference = ((value & 0xF0U) << 4) + (value & 0x0FU) - 0x8989U; + uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; - buffer[startingIndex + 1] = (byte)packedResult; - buffer[startingIndex] = (byte)(packedResult >> 8); + buffer[startingIndex + 1] = (byte)packedResult; + buffer[startingIndex] = (byte)(packedResult >> 8); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ToCharsBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) { - uint difference = ((value & 0xF0U) << 4) + (value & 0x0FU) - 0x8989U; - uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; + unchecked + { + uint difference = ((value & 0xF0U) << 4) + (value & 0x0FU) - 0x8989U; + uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; - buffer[startingIndex + 1] = (char)(packedResult & 0xFF); - buffer[startingIndex] = (char)(packedResult >> 8); + buffer[startingIndex + 1] = (char)(packedResult & 0xFF); + buffer[startingIndex] = (char)(packedResult >> 8); + } } public static void EncodeToUtf16(ReadOnlySpan bytes, Span chars, Casing casing = Casing.Upper) @@ -182,13 +188,16 @@ internal static class HexConverter [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromLowerChar(int c) { - if ((uint)(c - '0') <= '9' - '0') - return c - '0'; + unchecked + { + if ((uint)(c - '0') <= '9' - '0') + return c - '0'; - if ((uint)(c - 'a') <= 'f' - 'a') - return c - 'a' + 10; + if ((uint)(c - 'a') <= 'f' - 'a') + return c - 'a' + 10; - return 0xFF; + return 0xFF; + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -200,13 +209,13 @@ internal static class HexConverter [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexUpperChar(int c) { - return (uint)(c - '0') <= 9 || (uint)(c - 'A') <= ('F' - 'A'); + return unchecked((uint)(c - '0') <= 9 || (uint)(c - 'A') <= ('F' - 'A')); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexLowerChar(int c) { - return (uint)(c - '0') <= 9 || (uint)(c - 'a') <= ('f' - 'a'); + return unchecked((uint)(c - '0') <= 9 || (uint)(c - 'a') <= ('f' - 'a')); } /// Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit. @@ -229,4 +238,4 @@ internal static class HexConverter 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 239 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 255 }; -} +} \ No newline at end of file diff --git a/src/LibHac/Util/StringUtils.cs b/src/LibHac/Util/StringUtils.cs index e3f561b7..7ae55799 100644 --- a/src/LibHac/Util/StringUtils.cs +++ b/src/LibHac/Util/StringUtils.cs @@ -159,7 +159,7 @@ public static class StringUtils private static byte ToLowerAsciiInvariant(byte c) { - if ((uint)(c - 'A') <= 'Z' - 'A') + if (unchecked((uint)(c - 'A') <= 'Z' - 'A')) { c = (byte)(c | 0x20); } @@ -240,12 +240,12 @@ public static class StringUtils public static bool IsAlpha(byte c) { - return (c | 0x20u) - (byte)'a' <= 'z' - 'a'; + return unchecked((c | 0x20u) - (byte)'a' <= 'z' - 'a'); } public static bool IsDigit(byte c) { - return (uint)(c - (byte)'0') <= 9; + return unchecked((uint)(c - (byte)'0') <= 9); } public static bool IsHexDigit(byte c) @@ -316,4 +316,4 @@ public static class StringUtils { return HexConverter.ToString(bytes); } -} +} \ No newline at end of file