diff --git a/IonKiwi.lz4/LZ4RawUtility.cs b/IonKiwi.lz4/LZ4RawUtility.cs index e3b6dad1..e5a9219c 100644 --- a/IonKiwi.lz4/LZ4RawUtility.cs +++ b/IonKiwi.lz4/LZ4RawUtility.cs @@ -293,15 +293,23 @@ public static unsafe int LZ41_Stream_Decompress(Stream inputStream, Stream outpu /* Num Offsets */ inputStream.Position = initialPosition + compressedFileSize.Value - 12; int numOffsets = br.ReadInt32(); + if (numOffsets <= 0 || numOffsets > (compressedFileSize.Value - 12) / 4) + throw new Exception($"Invalid numOffsets in LZ41 footer: {numOffsets}"); /* File Size */ - if(!length.HasValue) + if(!length.HasValue) + { length = br.ReadInt32(); + if (length <= 0) + throw new Exception($"Invalid uncompressed size in LZ41 footer: {length}"); + } else inputStream.Position += 4; /* Block Size */ int blockSize = br.ReadInt32(); + if (blockSize <= 0) + throw new Exception($"Invalid block size in LZ41 footer: {blockSize}"); /* Read the offsets tail */ inputStream.Position = initialPosition + (compressedFileSize.Value - 12 - (numOffsets * 4)); @@ -315,6 +323,9 @@ public static unsafe int LZ41_Stream_Decompress(Stream inputStream, Stream outpu int currentBlock = offset.Value / blockSize; int endBlock = ((offset.Value + length.Value - 1) / blockSize) + 1; + if (currentBlock < 0 || endBlock >= numOffsets) + throw new Exception($"Requested range exceeds block table (blocks {currentBlock}–{endBlock}, numOffsets={numOffsets})"); + /* Seek to the first block to read */ inputStream.Position = initialPosition + offsets[currentBlock];