From c3e0b99002839f9221833797aafbcca389eeb94b Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 23 May 2022 20:48:34 -0700 Subject: [PATCH] CHM decompressor cleanup --- .../External/libmspack/CHM/Compressor.cs | 6 +- .../External/libmspack/CHM/Decompressor.cs | 743 +++++++++--------- 2 files changed, 384 insertions(+), 365 deletions(-) diff --git a/BurnOutSharp/External/libmspack/CHM/Compressor.cs b/BurnOutSharp/External/libmspack/CHM/Compressor.cs index 99614f78..9b1144ef 100644 --- a/BurnOutSharp/External/libmspack/CHM/Compressor.cs +++ b/BurnOutSharp/External/libmspack/CHM/Compressor.cs @@ -74,7 +74,7 @@ namespace LibMSPackSharp.CHM /// an error code, or MSPACK_ERR_OK if successful /// /// - public Func Generate; + public Error Generate(CompressFile[] fileList, string outputFile) => throw new NotImplementedException(); /// /// Specifies whether a temporary file is used during CHM generation. @@ -130,7 +130,7 @@ namespace LibMSPackSharp.CHM /// /// an error code, or MSPACK_ERR_OK if successful /// - public Func UseTemporaryFile; + public Error UseTemporaryFile(bool useTempFile, string tempFile) => throw new NotImplementedException(); /// /// Sets a CHM compression engine parameter. @@ -142,7 +142,7 @@ namespace LibMSPackSharp.CHM /// is a problem with either parameter or value. /// /// - public Func SetParam; + public Error SetParam(Parameters param, int value) => throw new NotImplementedException(); #endregion } diff --git a/BurnOutSharp/External/libmspack/CHM/Decompressor.cs b/BurnOutSharp/External/libmspack/CHM/Decompressor.cs index d2e8e0f4..97bffc8b 100644 --- a/BurnOutSharp/External/libmspack/CHM/Decompressor.cs +++ b/BurnOutSharp/External/libmspack/CHM/Decompressor.cs @@ -52,11 +52,8 @@ namespace LibMSPackSharp.CHM /// The filename pointer should be considered "in use" until close() is /// called on the CHM helpfile. /// - /// - /// the filename of the CHM helpfile. This is passed - /// directly to mspack_system::open(). - /// - /// a pointer to a mschmd_header structure, or NULL on failure + /// The filename of the CHM helpfile. This is passed directly to SystemImpl.Open(). + /// A pointer to a CHM structure, or NULL on failure /// public CHM Open(string filename) => RealOpen(filename, true); @@ -72,25 +69,13 @@ namespace LibMSPackSharp.CHM /// mschmd_file pointers referencing that CHM are also now invalid, and /// cannot be used again. /// - /// the CHM helpfile to close + /// The CHM helpfile to close /// /// public void Close(CHM chm) { Error = Error.MSPACK_ERR_OK; - // Free files - DecompressFile fi, nfi; - for (fi = chm.Files; fi != null; fi = nfi) - { - nfi = fi.Next; - } - - for (fi = chm.SysFiles; fi != null; fi = nfi) - { - nfi = fi.Next; - } - // If this CHM was being decompressed, free decompression state if (State != null && (State.Header == chm)) { @@ -123,32 +108,27 @@ namespace LibMSPackSharp.CHM CHM chm = file.Section.Header; - // Create decompression state if it doesn't exist - if (State == null) + // Close existing file handles + System.Close(State?.InputFileHandle); + System.Close(State?.OutputFileHandle); + + // Allocate generic decompression state + State = new DecompressState() { - State = new DecompressState(); - State.Header = chm; - State.Offset = 0; - State.State = null; - State.System = System; - State.System.Write = SysWrite; - State.InputFileHandle = null; - State.OutputFileHandle = null; - } + Header = chm, + Offset = 0, + State = null, + System = System, + InputFileHandle = null, + OutputFileHandle = null, + }; + + State.System.Write = SysWrite; // Open input chm file if not open, or the open one is a different chm - if (State.InputFileHandle == null || (State.Header != chm)) - { - System.Close(State.InputFileHandle); - System.Close(State.OutputFileHandle); - - State.Header = chm; - State.Offset = 0; - State.State = null; - State.InputFileHandle = System.Open(chm.Filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (State.InputFileHandle == null) - return Error = Error.MSPACK_ERR_OPEN; - } + State.InputFileHandle = System.Open(chm.Filename, OpenMode.MSPACK_SYS_OPEN_READ); + if (State.InputFileHandle == null) + return Error = Error.MSPACK_ERR_OPEN; // Open file for output FileStream fh = System.Open(filename, OpenMode.MSPACK_SYS_OPEN_WRITE); @@ -164,88 +144,22 @@ namespace LibMSPackSharp.CHM Error = Error.MSPACK_ERR_OK; + // Decompress the file based on section ID switch (file.Section.ID) { // Uncompressed section file case 0: - // Simple seek + copy - if (!System.Seek(State.InputFileHandle, file.Section.Header.Sec0.Offset + file.Offset, SeekMode.MSPACK_SYS_SEEK_START)) - { - Error = Error.MSPACK_ERR_SEEK; - } - else - { - byte[] buf = new byte[512]; - long length = file.Length; - while (length > 0) - { - int run = 512; - if (run > length) - run = (int)length; - - if (System.Read(State.InputFileHandle, buf, 0, run) != run) - { - Error = Error.MSPACK_ERR_READ; - break; - } - - if (System.Write(fh, buf, 0, run) != run) - { - Error = Error.MSPACK_ERR_WRITE; - break; - } - - length -= run; - } - } - break; + return ExtractSection0File(file, fh); // MSCompressed section file case 1: - // (Re)initialise compression state if we it is not yet initialised, - // or we have advanced too far and have to backtrack - if (State.State == null || (file.Offset < State.Offset)) - { - if (State.State != null) - State.State = null; + return ExtractSection1File(file, fh); - if (InitDecompressor(file) != Error.MSPACK_ERR_OK) - break; - } - - // Seek to input data - if (!System.Seek(State.InputFileHandle, State.InOffset, SeekMode.MSPACK_SYS_SEEK_START)) - { - Error = Error.MSPACK_ERR_SEEK; - break; - } - - // Get to correct offset. - State.OutputFileHandle = null; - long bytes; - if ((bytes = file.Offset - State.Offset) != 0) - Error = LZX.Decompress(State.State, bytes); - - // If getting to the correct offset was error free, unpack file - if (Error == Error.MSPACK_ERR_OK) - { - State.OutputFileHandle = fh; - Error = LZX.Decompress(State.State, file.Length); - } - - // Save offset in input source stream, in case there is a section 0 - // file between now and the next section 1 file extracted - State.InOffset = System.Tell(State.InputFileHandle); - - // If an LZX error occured, the LZX decompressor is now useless - if (Error != Error.MSPACK_ERR_OK) - State.State = null; - - break; + // Should not happen + default: + System.Close(fh); + return Error = Error.MSPACK_ERR_ARGS; } - - System.Close(fh); - return Error; } /// @@ -274,179 +188,6 @@ namespace LibMSPackSharp.CHM /// public CHM FastOpen(string filename) => RealOpen(filename, false); - /// - /// Finds file details quickly. - /// - /// Instead of reading all CHM helpfile headers and building a list of - /// files, fast_open() and fast_find() are intended for finding file - /// details only when they are needed.The CHM file format includes an - /// on-disk file index to allow this. - /// - /// Given a case-sensitive filename, fast_find() will search the on-disk - /// index for that file. - /// - /// If the file was found, the caller-provided mschmd_file structure will - /// be filled out like so: - /// - section: the correct value for the found file - /// - offset: the correct value for the found file - /// - length: the correct value for the found file - /// - all other structure elements: NULL or 0 - /// - /// If the file was not found, MSPACK_ERR_OK will still be returned as the - /// result, but the caller-provided structure will be filled out like so: - /// - section: NULL - /// - offset: 0 - /// - length: 0 - /// - all other structure elements: NULL or 0 - /// - /// This method is intended to be used in conjunction with CHM helpfiles - /// opened with fast_open(), but it also works with helpfiles opened - /// using the regular open(). - /// - /// the CHM helpfile to search for the file - /// the filename of the file to search for - /// a pointer to a caller-provded mschmd_file structure - /// an error code, or MSPACK_ERR_OK if successful - /// - /// - /// - /// - public Error FastFind(CHM chm, string filename, DecompressFile f_ptr) - { - // p and end are initialised to prevent MSVC warning about "potentially" - // uninitialised usage. This is provably untrue, but MS won't fix: - // https://developercommunity.visualstudio.com/content/problem/363489/c4701-false-positive-warning.html - byte[] chunk = new byte[0]; - int p = -1, end = -1, result = -1; - Error err = Error.MSPACK_ERR_OK; - uint n, sec; - - if (chm == null || f_ptr == null) - return Error.MSPACK_ERR_ARGS; - - // Clear the results structure - f_ptr = new DecompressFile(); - - FileStream fh = System.Open(chm.Filename, OpenMode.MSPACK_SYS_OPEN_READ); - if (fh == null) - return Error.MSPACK_ERR_OPEN; - - // Go through PMGI chunk hierarchy to reach PMGL chunk - if (chm.HeaderSection1.IndexRoot < chm.HeaderSection1.NumChunks) - { - n = chm.HeaderSection1.IndexRoot; - for (; ; ) - { - if ((chunk = ReadChunk(chm, fh, n)) == null) - { - System.Close(fh); - return Error; - } - - // Search PMGI/PMGL chunk. exit early if no entry found - if ((result = SearchChunk(chm, chunk, filename, ref p, ref end)) <= 0) - break; - - // Found result. loop around for next chunk if this is PMGI - if (chunk[3] == 0x4C) - { - break; - } - else - { - // READ_ENCINT(n) - n = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - n = (uint)((n << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - } - } - else - { - // PMGL chunks only, search from first_pmgl to last_pmgl - for (n = chm.HeaderSection1.FirstPMGL; n <= chm.HeaderSection1.LastPMGL; n = BitConverter.ToUInt32(chunk, 0x0010)) - { - if ((chunk = ReadChunk(chm, fh, n)) == null) - { - err = Error; - break; - } - - // Search PMGL chunk. exit if file found - if ((result = SearchChunk(chm, chunk, filename, ref p, ref end)) > 0) - break; - - // Stop simple infinite loops: can't visit the same chunk twice - if (n == BitConverter.ToUInt32(chunk, 0x0010)) - break; - } - } - - // If we found a file, read it - if (result > 0) - { - // READ_ENCINT(sec) - sec = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - sec = (uint)((sec << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - - f_ptr.Section = sec == 0 ? chm.Sec0 as Section : chm.Sec1 as Section; - - // READ_ENCINT(f_ptr.Offset) - f_ptr.Offset = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - f_ptr.Offset = (uint)((f_ptr.Offset << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - - // READ_ENCINT(f_ptr.Length) - f_ptr.Length = 0; - do - { - if (p >= end) - { - Console.WriteLine("Read beyond end of chunk entries"); - System.Close(fh); - return Error = Error.MSPACK_ERR_DATAFORMAT; - } - - f_ptr.Length = (uint)((f_ptr.Length << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); - } - else if (result < 0) - { - err = Error.MSPACK_ERR_DATAFORMAT; - } - - System.Close(fh); - return Error = err; - } - #endregion #region Decompress State @@ -458,9 +199,6 @@ namespace LibMSPackSharp.CHM /// internal Error InitDecompressor(DecompressFile file) { - int entry; - byte[] data; - MSCompressedSection sec = file.Section as MSCompressedSection; // Ensure we have a mscompressed content section @@ -486,7 +224,8 @@ namespace LibMSPackSharp.CHM return Error = Error.MSPACK_ERR_DATAFORMAT; } - if ((data = ReadSysFile(sec.Control)) == null) + byte[] data = ReadSysFile(sec.Control); + if (data == null) { Console.WriteLine("Can't read mscompressed control data file"); return Error; @@ -510,7 +249,7 @@ namespace LibMSPackSharp.CHM } // Which reset table entry would we like? - entry = (int)(file.Offset / lzxControlData.ResetInterval); + int entry = (int)(file.Offset / lzxControlData.ResetInterval); // Convert from reset interval multiple (usually 64k) to 32k frames entry *= (int)lzxControlData.ResetInterval / LZX.LZX_FRAME_SIZE; @@ -521,13 +260,15 @@ namespace LibMSPackSharp.CHM // The uncompressed length given in the reset table is dishonest. // The uncompressed data is always padded out from the given // uncompressed length up to the next reset interval + length += lzxControlData.ResetInterval - 1; length &= -lzxControlData.ResetInterval; } else { - // if we can't read the reset table entry, just start from + // If we can't read the reset table entry, just start from // the beginning. Use spaninfo to get the uncompressed length + entry = 0; offset = 0; err = ReadSpanInfo(sec, out length); @@ -586,13 +327,286 @@ namespace LibMSPackSharp.CHM } // Unknown file to write to - return 0; + return -1; } #endregion #region Helpers + /// + /// Extract a Section 0 file + /// + private Error ExtractSection0File(DecompressFile file, FileStream fh) + { + // Simple seek + copy + if (!System.Seek(State.InputFileHandle, file.Section.Header.Sec0.Offset + file.Offset, SeekMode.MSPACK_SYS_SEEK_START)) + { + System.Close(fh); + return Error = Error.MSPACK_ERR_SEEK; + } + + byte[] buf = new byte[512]; + long length = file.Length; + while (length > 0) + { + int run = 512; + if (run > length) + run = (int)length; + + if (System.Read(State.InputFileHandle, buf, 0, run) != run) + { + System.Close(fh); + return Error = Error.MSPACK_ERR_READ; + } + + if (System.Write(fh, buf, 0, run) != run) + { + System.Close(fh); + return Error = Error.MSPACK_ERR_WRITE; + } + + length -= run; + } + + System.Close(fh); + return Error = Error.MSPACK_ERR_OK; + } + + /// + /// Extract a Section 1 file + /// + private Error ExtractSection1File(DecompressFile file, FileStream fh) + { + // (Re)initialise compression state if we it is not yet initialised, + // or we have advanced too far and have to backtrack + if (State.State == null || (file.Offset < State.Offset)) + { + if (State.State != null) + State.State = null; + + if (InitDecompressor(file) != Error.MSPACK_ERR_OK) + { + System.Close(fh); + return Error; + } + } + + // Seek to input data + if (!System.Seek(State.InputFileHandle, State.InOffset, SeekMode.MSPACK_SYS_SEEK_START)) + { + System.Close(fh); + return Error = Error.MSPACK_ERR_SEEK; + } + + // Get to correct offset. + State.OutputFileHandle = null; + long bytes; + if ((bytes = file.Offset - State.Offset) != 0) + Error = LZX.Decompress(State.State, bytes); + + // If getting to the correct offset was error free, unpack file + if (Error == Error.MSPACK_ERR_OK) + { + State.OutputFileHandle = fh; + Error = LZX.Decompress(State.State, file.Length); + } + + // Save offset in input source stream, in case there is a section 0 + // file between now and the next section 1 file extracted + State.InOffset = System.Tell(State.InputFileHandle); + + // If an LZX error occured, the LZX decompressor is now useless + if (Error != Error.MSPACK_ERR_OK) + State.State = null; + + System.Close(fh); + return Error; + } + + /// + /// Finds file details quickly. + /// + /// Instead of reading all CHM helpfile headers and building a list of + /// files, fast_open() and fast_find() are intended for finding file + /// details only when they are needed.The CHM file format includes an + /// on-disk file index to allow this. + /// + /// Given a case-sensitive filename, fast_find() will search the on-disk + /// index for that file. + /// + /// If the file was found, the caller-provided mschmd_file structure will + /// be filled out like so: + /// - section: the correct value for the found file + /// - offset: the correct value for the found file + /// - length: the correct value for the found file + /// - all other structure elements: NULL or 0 + /// + /// If the file was not found, MSPACK_ERR_OK will still be returned as the + /// result, but the caller-provided structure will be filled out like so: + /// - section: NULL + /// - offset: 0 + /// - length: 0 + /// - all other structure elements: NULL or 0 + /// + /// This method is intended to be used in conjunction with CHM helpfiles + /// opened with fast_open(), but it also works with helpfiles opened + /// using the regular open(). + /// + /// the CHM helpfile to search for the file + /// the filename of the file to search for + /// a pointer to a caller-provded mschmd_file structure + /// an error code, or MSPACK_ERR_OK if successful + /// + /// + /// + /// + private Error FastFind(CHM chm, string filename, DecompressFile f_ptr) + { + // p and end are initialised to prevent MSVC warning about "potentially" + // uninitialised usage. This is provably untrue, but MS won't fix: + // https://developercommunity.visualstudio.com/content/problem/363489/c4701-false-positive-warning.html + int p = -1, end = -1, result = -1; + Error err = Error.MSPACK_ERR_OK; + uint n, sec; + + if (chm == null || f_ptr == null) + return Error.MSPACK_ERR_ARGS; + + // Clear the results structure + f_ptr = new DecompressFile(); + + FileStream fh = System.Open(chm.Filename, OpenMode.MSPACK_SYS_OPEN_READ); + if (fh == null) + return Error.MSPACK_ERR_OPEN; + + // Go through PMGI chunk hierarchy to reach PMGL chunk + byte[] chunk = null; + if (chm.HeaderSection1.IndexRoot < chm.HeaderSection1.NumChunks) + { + n = chm.HeaderSection1.IndexRoot; + for (; ; ) + { + chunk = ReadChunk(chm, fh, n); + if (chunk == null) + { + System.Close(fh); + return Error; + } + + // Search PMGI/PMGL chunk. exit early if no entry found + if ((result = SearchChunk(chm, chunk, filename, ref p, ref end)) <= 0) + break; + + // Found result. loop around for next chunk if this is PMGI + if (chunk[3] == 0x4C) + { + break; + } + else + { + // READ_ENCINT(n) + { + (n) = 0; + do + { + if (p >= end) + { + Console.WriteLine("Read beyond end of chunk entries"); + System.Close(fh); + return Error = Error.MSPACK_ERR_DATAFORMAT; + } + + (n) = (uint)(((n) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } + } + } + } + else + { + // PMGL chunks only, search from first_pmgl to last_pmgl + for (n = chm.HeaderSection1.FirstPMGL; n <= chm.HeaderSection1.LastPMGL; n = BitConverter.ToUInt32(chunk, 0x0010)) + { + chunk = ReadChunk(chm, fh, n); + if (chunk == null) + { + err = Error; + break; + } + + // Search PMGL chunk. exit if file found + if ((result = SearchChunk(chm, chunk, filename, ref p, ref end)) > 0) + break; + + // Stop simple infinite loops: can't visit the same chunk twice + if (n == BitConverter.ToUInt32(chunk, 0x0010)) + break; + } + } + + // If we found a file, read it + if (result > 0) + { + // READ_ENCINT(sec) + { + (sec) = 0; + do + { + if (p >= end) + { + Console.WriteLine("Read beyond end of chunk entries"); + System.Close(fh); + return Error = Error.MSPACK_ERR_DATAFORMAT; + } + + (sec) = (uint)(((sec) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } + + f_ptr.Section = sec == 0 ? chm.Sec0 as Section : chm.Sec1 as Section; + + // READ_ENCINT(f_ptr.Offset) + { + (f_ptr.Offset) = 0; + do + { + if (p >= end) + { + Console.WriteLine("Read beyond end of chunk entries"); + System.Close(fh); + return Error = Error.MSPACK_ERR_DATAFORMAT; + } + + (f_ptr.Offset) = (((f_ptr.Offset) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } + + // READ_ENCINT(f_ptr.Length) + { + (f_ptr.Length) = 0; + do + { + if (p >= end) + { + Console.WriteLine("Read beyond end of chunk entries"); + System.Close(fh); + return Error = Error.MSPACK_ERR_DATAFORMAT; + } + + (f_ptr.Length) = (((f_ptr.Length) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } + } + else if (result < 0) + { + err = Error.MSPACK_ERR_DATAFORMAT; + } + + System.Close(fh); + return Error = err; + } + /// /// Uses chmd_fast_find to locate a system file, and fills out that system /// file's entry and links it into the list of system files. Returns zero @@ -611,8 +625,6 @@ namespace LibMSPackSharp.CHM if (FastFind(sec.Header, name, result) != Error.MSPACK_ERR_OK || result.Section == null) return Error.MSPACK_ERR_DATAFORMAT; - f_ptr = new DecompressFile(); - // Copy result f_ptr = result; f_ptr.Filename = name; @@ -887,20 +899,20 @@ namespace LibMSPackSharp.CHM while (numEntries-- != 0) { // READ_ENCINT(nameLen) - nameLen = 0; - do { - if (p >= end) + (nameLen) = 0; + do { - if (numEntries >= 0) + if (p >= end) { - Console.WriteLine("Chunk ended before all entries could be read"); - errors++; + Console.WriteLine("Read beyond end of chunk entries"); + System.Close(fh); + return Error = Error.MSPACK_ERR_DATAFORMAT; } - } - nameLen = (uint)((nameLen << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); + (nameLen) = (uint)(((nameLen) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } if (nameLen > (uint)(end - p)) { @@ -914,52 +926,54 @@ namespace LibMSPackSharp.CHM name = p; p += (int)nameLen; // READ_ENCINT(section) - section = 0; - do { - if (p >= end) + (section) = 0; + do { - if (numEntries >= 0) + if (p >= end) { - Console.WriteLine("Chunk ended before all entries could be read"); - errors++; + Console.WriteLine("Read beyond end of chunk entries"); + System.Close(fh); + return Error = Error.MSPACK_ERR_DATAFORMAT; } - } - section = (uint)((section << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); + (section) = (uint)(((section) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } // READ_ENCINT(offset) - offset = 0; - do { - if (p >= end) + (offset) = 0; + do { - if (numEntries >= 0) + if (p >= end) { - Console.WriteLine("Chunk ended before all entries could be read"); - errors++; + Console.WriteLine("Read beyond end of chunk entries"); + System.Close(fh); + return Error = Error.MSPACK_ERR_DATAFORMAT; } - } - offset = (offset << 7) | (chunk[p] & 0x7F); - } while ((chunk[p++] & 0x80) != 0); + (offset) = (((offset) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } // READ_ENCINT(length) - length = 0; - do { - if (p >= end) + (length) = 0; + do { - if (numEntries >= 0) + if (p >= end) { - Console.WriteLine("Chunk ended before all entries could be read"); - errors++; + Console.WriteLine("Read beyond end of chunk entries"); + System.Close(fh); + return Error = Error.MSPACK_ERR_DATAFORMAT; } - } - length = (length << 7) | (chunk[p] & 0x7F); - } while ((chunk[p++] & 0x80) != 0); + (length) = (((length) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } + + // READ_ENCINT(length) // Ignore blank or one-char (e.g. "/") filenames we'd return as blank if (nameLen < 2 || chunk[name + 0] == 0x00 || chunk[name + 1] == 0x00) @@ -1240,8 +1254,6 @@ namespace LibMSPackSharp.CHM if (err != Error.MSPACK_ERR_OK) return -1; - // TODO: Figure out what `entriesOff` does. It feels like it's being used wrong - // PMGL chunk or PMGI chunk? (note: read_chunk() has already // checked the rest of the characters in the chunk signature) if (pmgHeader.IsPMGL()) @@ -1267,7 +1279,7 @@ namespace LibMSPackSharp.CHM if (numEntries == 0) { - Console.Write("chunk has no entries"); + Console.Write("Chunk has no entries"); return -1; } @@ -1298,17 +1310,19 @@ namespace LibMSPackSharp.CHM p = (int)(entries + (midpoint != 0 ? BitConverter.ToUInt16(chunk, (int)(start - (midpoint << 1))) : 0)); // READ_ENCINT(nameLen) - nameLen = 0; - do { - if (p >= end) + (nameLen) = 0; + do { - Console.WriteLine("reached end of chunk data while searching"); - return -1; - } + if (p >= end) + { + Console.WriteLine("Reached end of chunk data while searching"); + return -1; + } - nameLen = (uint)((nameLen << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); + (nameLen) = (uint)(((nameLen) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } if (nameLen > (uint)(end - p)) { @@ -1367,17 +1381,19 @@ namespace LibMSPackSharp.CHM while (numEntries-- > 0) { // READ_ENCINT(nameLen) - nameLen = 0; - do { - if (p >= end) + (nameLen) = 0; + do { - Console.WriteLine("reached end of chunk data while searching"); - return -1; - } + if (p >= end) + { + Console.WriteLine("Reached end of chunk data while searching"); + return -1; + } - nameLen = (uint)((nameLen << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); + (nameLen) = (uint)(((nameLen) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } if (nameLen > (uint)(end - p)) { @@ -1426,18 +1442,21 @@ namespace LibMSPackSharp.CHM result = p; // Store potential final result // Skip chunk number - // READ_ENCINT(R) - right = 0; - do - { - if (p >= end) - { - Console.WriteLine("reached end of chunk data while searching"); - return -1; - } - right = (uint)((right << 7) | (chunk[p] & 0x7F)); - } while ((chunk[p++] & 0x80) != 0); + // READ_ENCINT(right) + { + (right) = 0; + do + { + if (p >= end) + { + Console.WriteLine("Reached end of chunk data while searching"); + return -1; + } + + (right) = (uint)(((right) << 7) | (chunk[p++] & 0x7F)); + } while ((chunk[p++] & 0x80) != 0); + } } }