From 8fdd96209cda51bfbf9358b016ea29b2238f2043 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 5 Mar 2022 17:14:25 -0800 Subject: [PATCH] Deduplicate some logic No need to length check in the SwishCrypto hash check, as the methods pre-check length as well. Extract checksum footer check for Gen5 saves --- .../Saves/Encryption/SwishCrypto/SCBlock.cs | 4 ++++ .../Encryption/SwishCrypto/SwishCrypto.cs | 18 ----------------- PKHeX.Core/Saves/Util/SaveUtil.cs | 20 +++++++++++-------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/PKHeX.Core/Saves/Encryption/SwishCrypto/SCBlock.cs b/PKHeX.Core/Saves/Encryption/SwishCrypto/SCBlock.cs index fcce448f8..1f9d8b25e 100644 --- a/PKHeX.Core/Saves/Encryption/SwishCrypto/SCBlock.cs +++ b/PKHeX.Core/Saves/Encryption/SwishCrypto/SCBlock.cs @@ -203,6 +203,10 @@ public static SCBlock ReadFromOffset(ReadOnlySpan data, ref int offset) } } + /// + /// Merges the properties from into this object. + /// + /// Block to copy all values from. public void CopyFrom(SCBlock other) { if (Type.IsBoolean()) diff --git a/PKHeX.Core/Saves/Encryption/SwishCrypto/SwishCrypto.cs b/PKHeX.Core/Saves/Encryption/SwishCrypto/SwishCrypto.cs index 7ebeedaf5..fd0e19676 100644 --- a/PKHeX.Core/Saves/Encryption/SwishCrypto/SwishCrypto.cs +++ b/PKHeX.Core/Saves/Encryption/SwishCrypto/SwishCrypto.cs @@ -82,24 +82,6 @@ private static byte[] ComputeHash(byte[] data) /// True if hash matches public static bool GetIsHashValid(byte[] data) { - if (!SaveUtil.SizesSWSH.Contains(data.Length)) - return false; - - var hash = ComputeHash(data); - var span = data.AsSpan()[^hash.Length..]; - return span.SequenceEqual(hash); - } - - /// - /// Checks if the file is a rough example of a save file. - /// - /// Encrypted save data - /// True if hash matches - public static bool GetIsHashValidLA(byte[] data) - { - if (data.Length is not (SaveUtil.SIZE_G8LA or SaveUtil.SIZE_G8LA_1)) - return false; - var hash = ComputeHash(data); var span = data.AsSpan()[^hash.Length..]; return span.SequenceEqual(hash); diff --git a/PKHeX.Core/Saves/Util/SaveUtil.cs b/PKHeX.Core/Saves/Util/SaveUtil.cs index e26edd9b4..602b52564 100644 --- a/PKHeX.Core/Saves/Util/SaveUtil.cs +++ b/PKHeX.Core/Saves/Util/SaveUtil.cs @@ -428,16 +428,20 @@ private static GameVersion GetIsG5SAV(ReadOnlySpan data) if (data.Length != SIZE_G5RAW) return Invalid; - // check the checksum block validity; nobody would normally modify this region - ushort chk1 = ReadUInt16LittleEndian(data[(SIZE_G5BW - 0x100 + 0x8C + 0xE)..]); - ushort actual1 = Checksums.CRC16_CCITT(data.Slice(SIZE_G5BW - 0x100, 0x8C)); - if (chk1 == actual1) + // check the checksum footer block validity; nobody would normally modify this region + if (IsValidFooter(data, SIZE_G5BW, 0x8C)) return BW; - ushort chk2 = ReadUInt16LittleEndian(data[(SIZE_G5B2W2 - 0x100 + 0x94 + 0xE)..]); - ushort actual2 = Checksums.CRC16_CCITT(data.Slice(SIZE_G5B2W2 - 0x100, 0x94)); - if (chk2 == actual2) + if (IsValidFooter(data, SIZE_G5B2W2, 0x94)) return B2W2; return Invalid; + + static bool IsValidFooter(ReadOnlySpan data, int mainSize, int infoLength) + { + var footer = data.Slice(mainSize - 0x100, infoLength + 0x10); + ushort stored = ReadUInt16LittleEndian(footer[^2..]); + ushort actual = Checksums.CRC16_CCITT(footer[..infoLength]); + return stored == actual; + } } /// Checks to see if the data belongs to a Gen6 save @@ -514,7 +518,7 @@ private static GameVersion GetIsG8SAV_LA(byte[] data) if (data.Length is not (SIZE_G8LA or SIZE_G8LA_1)) return Invalid; - return SwishCrypto.GetIsHashValidLA(data) ? PLA : Invalid; + return SwishCrypto.GetIsHashValid(data) ? PLA : Invalid; } private static bool GetIsBank7(ReadOnlySpan data) => data.Length == SIZE_G7BANK && data[0] != 0;