diff --git a/Core/Archive/ArchiveMap.cs b/Core/Archive/ArchiveMap.cs index c0f31d89..4ab32b44 100644 --- a/Core/Archive/ArchiveMap.cs +++ b/Core/Archive/ArchiveMap.cs @@ -48,7 +48,7 @@ byte[] open(int skip = 0) case 1: buffer = open(4); offset = 0; - return new MemoryStream(LZSS.DecompressAllNew(buffer, false)); + return new MemoryStream(LZSS.DecompressAllNew(buffer, @in.UncompressedSize, false)); case 2: buffer = open(); @@ -182,7 +182,7 @@ public byte[] GetBinaryFile(string input, Stream data) return buffer; case 1: - return LZSS.DecompressAllNew(buffer); + return LZSS.DecompressAllNew(buffer, fi.UncompressedSize); case 2: return LZ4Uncompress(buffer, fi.UncompressedSize); diff --git a/Core/Archive/ArchiveWorker.cs b/Core/Archive/ArchiveWorker.cs index 87bc3a4f..53321418 100644 --- a/Core/Archive/ArchiveWorker.cs +++ b/Core/Archive/ArchiveWorker.cs @@ -515,7 +515,7 @@ private byte[] GetBinaryFile(string fileName, int loc, bool cache) temp = GetCompressedData(FI, out int size); Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)} :: extracting: {fileName}"); - temp = temp == null ? null : FI.CompressionType == 2 ? ArchiveMap.LZ4Uncompress(temp, FI.UncompressedSize) : FI.CompressionType == 1 ? LZSS.DecompressAllNew(temp) : temp; + temp = temp == null ? null : FI.CompressionType == 2 ? ArchiveMap.LZ4Uncompress(temp, FI.UncompressedSize) : FI.CompressionType == 1 ? LZSS.DecompressAllNew(temp,FI.UncompressedSize) : temp; if (temp != null && cache && LocalTryAdd(fileName, temp)) { Memory.Log.WriteLine($"{nameof(ArchiveWorker)}::{nameof(GetBinaryFile)} :: cached: {fileName}"); diff --git a/Core/Archive/Compression/LZSS.cs b/Core/Archive/Compression/LZSS.cs index 6dfafddd..10fa3b1e 100644 --- a/Core/Archive/Compression/LZSS.cs +++ b/Core/Archive/Compression/LZSS.cs @@ -29,7 +29,7 @@ Please send me your improved versions. private static readonly int THRESHOLD = 2; private static readonly int EOF = -1; - public static byte[] DecompressAllNew(byte[] data, bool skip = false) + public static byte[] DecompressAllNew(byte[] data, int uncompressedsize, bool skip = false) { //Memory.Log.WriteLine($"{nameof(LZSS)}::{nameof(DecompressAllNew)} :: decompressing data"); byte[] outfilearray; @@ -37,6 +37,8 @@ public static byte[] DecompressAllNew(byte[] data, bool skip = false) { Decode(infile, out outfilearray); } + if (uncompressedsize > 0 && outfilearray.Length != uncompressedsize) + throw new InvalidDataException($"{nameof(LZSS)}::{nameof(DecompressAllNew)} Expected size ({uncompressedsize}) != ({outfilearray.Length})"); return outfilearray; } diff --git a/Core/Saves/Saves.cs b/Core/Saves/Saves.cs index 8b9c8d37..f5511637 100644 --- a/Core/Saves/Saves.cs +++ b/Core/Saves/Saves.cs @@ -132,13 +132,15 @@ private static void Read(string file, out Data d) if (fs.Length >= 5) { size = br.ReadInt32(); - byte[] tmp = br.ReadBytes((int)fs.Length - sizeof(uint)); - decmp = LZSS.DecompressAllNew(tmp); + if ((int)fs.Length - sizeof(uint) == size) + { + byte[] tmp = br.ReadBytes((int)fs.Length - sizeof(uint)); + decmp = LZSS.DecompressAllNew(tmp, 0); + } } fs = null; } - - if (decmp == null || decmp.Length < size) + if (decmp == null) { Memory.Log.WriteLine($"{nameof(Saves)}::{nameof(Read)} Invalid file: {file}"); } diff --git a/Core/module_overture_debug.cs b/Core/module_overture_debug.cs index 0a31dbf5..fd4a56b4 100644 --- a/Core/module_overture_debug.cs +++ b/Core/module_overture_debug.cs @@ -313,7 +313,7 @@ public Splash(int splashNum, bool bNames = true, bool bLogo = false) return; } ArchiveBase aw = ArchiveWorker.Load(Memory.Archives.A_MAIN); - var lof = aw.GetListOfFiles(); + string[] lof = aw.GetListOfFiles(); loopsnames = lof.Where(x => x.IndexOf(loops, StringComparison.OrdinalIgnoreCase) > -1).OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList(); namesnames = lof.Where(x => x.IndexOf(names, StringComparison.OrdinalIgnoreCase) > -1).OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList(); logonames = lof.Where(x => x.IndexOf("ff8.lzs", StringComparison.OrdinalIgnoreCase) > -1).OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList(); @@ -385,10 +385,21 @@ private void ReadSplash() if (string.IsNullOrWhiteSpace(filename)) return; ArchiveBase aw = ArchiveWorker.Load(Memory.Archives.A_MAIN); byte[] buffer = aw.GetBinaryFile(filename); + string fn = Path.GetFileNameWithoutExtension(filename); - uint uncompSize = BitConverter.ToUInt32(buffer, 0); - buffer = buffer.Skip(4).ToArray(); //hotfix for new LZSS - buffer = LZSS.DecompressAllNew(buffer); + + if (buffer.Length <= 4) + { + Memory.Log.WriteLine($"{nameof(Module_overture_debug)}::{nameof(ReadSplash)} \"{filename}\" too small to read any data."); + return; + } + int compSize = BitConverter.ToInt32(buffer, 0); + if (compSize != buffer.Length - sizeof(int)) + { + Memory.Log.WriteLine($"{nameof(Module_overture_debug)}::{nameof(ReadSplash)} \"{filename}\" wrong size ({buffer.Length - sizeof(int)}) to be ({compSize})."); + return; + } + buffer = LZSS.DecompressAllNew(buffer, 0, true); TIM_OVERTURE tim = new TIM_OVERTURE(buffer); if ((fn.Equals("ff8", StringComparison.OrdinalIgnoreCase)) || (fn.IndexOf("loop", StringComparison.OrdinalIgnoreCase) >= 0)) {