mirror of
https://github.com/0x5eal/luau-unzip.git
synced 2025-04-10 17:20:53 +01:00
fix: deflate decompression failing for files with high compression ratio
This commit is contained in:
parent
6f4083f10f
commit
06b1f1a640
2 changed files with 305 additions and 300 deletions
|
@ -343,11 +343,13 @@ local function inflateUncompressedBlock(d: Data)
|
|||
end
|
||||
|
||||
--- Main decompression function that processes DEFLATE compressed data
|
||||
local function uncompress(source: buffer): buffer
|
||||
-- FIXME: This is a temporary solution to avoid a buffer overflow
|
||||
-- We likely want some type of reflection with the zip metadata to
|
||||
-- have a definitive buffer size
|
||||
local dest = buffer.create(buffer.len(source) * 7)
|
||||
local function uncompress(source: buffer, uncompressedSize: number?): buffer
|
||||
local dest = buffer.create(
|
||||
-- If the uncompressed size is known, we use that, otherwise we use a default
|
||||
-- size that is a 7 times more than the compressed size; this factor works
|
||||
-- well for most cases other than those with a very high compression ratio
|
||||
uncompressedSize or buffer.len(source) * 7
|
||||
)
|
||||
local d = Data.new(source, dest)
|
||||
|
||||
repeat
|
||||
|
|
|
@ -32,20 +32,23 @@ local function validateCrc(decompressed: buffer, validation: CrcValidationOption
|
|||
end
|
||||
end
|
||||
|
||||
local DECOMPRESSION_ROUTINES: { [number]: (buffer, validation: CrcValidationOptions) -> buffer } = table.freeze({
|
||||
local DECOMPRESSION_ROUTINES: { [number]: (buffer, number, CrcValidationOptions) -> buffer } =
|
||||
table.freeze({
|
||||
-- `STORE` decompression method - No compression
|
||||
[0x00] = function(buf, validation)
|
||||
[0x00] = function(buf, _, validation)
|
||||
validateCrc(buf, validation)
|
||||
return buf
|
||||
end,
|
||||
|
||||
-- `DEFLATE` decompression method - Compressed raw deflate chunks
|
||||
[0x08] = function(buf, validation)
|
||||
local decompressed = inflate(buf)
|
||||
[0x08] = function(buf, uncompressedSize, validation)
|
||||
-- FIXME: Why is uncompressedSize not getting inferred correctly although it
|
||||
-- is typed?
|
||||
local decompressed = inflate(buf, uncompressedSize :: any)
|
||||
validateCrc(decompressed, validation)
|
||||
return decompressed
|
||||
end,
|
||||
})
|
||||
})
|
||||
|
||||
-- TODO: ERROR HANDLING!
|
||||
|
||||
|
@ -364,7 +367,7 @@ function ZipReader.extract(self: ZipReader, entry: ZipEntry, options: Extraction
|
|||
error(`Unsupported compression, ID: {compressionMethod}`)
|
||||
end
|
||||
|
||||
content = decompress(content, {
|
||||
content = decompress(content, uncompressedSize, {
|
||||
expected = crcChecksum,
|
||||
skip = optionsOrDefault.skipCrcValidation,
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue