mirror of
https://github.com/0x5eal/luau-unzip.git
synced 2025-04-19 05:03:46 +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
|
end
|
||||||
|
|
||||||
--- Main decompression function that processes DEFLATE compressed data
|
--- Main decompression function that processes DEFLATE compressed data
|
||||||
local function uncompress(source: buffer): buffer
|
local function uncompress(source: buffer, uncompressedSize: number?): buffer
|
||||||
-- FIXME: This is a temporary solution to avoid a buffer overflow
|
local dest = buffer.create(
|
||||||
-- We likely want some type of reflection with the zip metadata to
|
-- If the uncompressed size is known, we use that, otherwise we use a default
|
||||||
-- have a definitive buffer size
|
-- size that is a 7 times more than the compressed size; this factor works
|
||||||
local dest = buffer.create(buffer.len(source) * 7)
|
-- 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)
|
local d = Data.new(source, dest)
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
|
|
|
@ -32,20 +32,23 @@ local function validateCrc(decompressed: buffer, validation: CrcValidationOption
|
||||||
end
|
end
|
||||||
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
|
-- `STORE` decompression method - No compression
|
||||||
[0x00] = function(buf, validation)
|
[0x00] = function(buf, _, validation)
|
||||||
validateCrc(buf, validation)
|
validateCrc(buf, validation)
|
||||||
return buf
|
return buf
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- `DEFLATE` decompression method - Compressed raw deflate chunks
|
-- `DEFLATE` decompression method - Compressed raw deflate chunks
|
||||||
[0x08] = function(buf, validation)
|
[0x08] = function(buf, uncompressedSize, validation)
|
||||||
local decompressed = inflate(buf)
|
-- FIXME: Why is uncompressedSize not getting inferred correctly although it
|
||||||
|
-- is typed?
|
||||||
|
local decompressed = inflate(buf, uncompressedSize :: any)
|
||||||
validateCrc(decompressed, validation)
|
validateCrc(decompressed, validation)
|
||||||
return decompressed
|
return decompressed
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- TODO: ERROR HANDLING!
|
-- TODO: ERROR HANDLING!
|
||||||
|
|
||||||
|
@ -364,7 +367,7 @@ function ZipReader.extract(self: ZipReader, entry: ZipEntry, options: Extraction
|
||||||
error(`Unsupported compression, ID: {compressionMethod}`)
|
error(`Unsupported compression, ID: {compressionMethod}`)
|
||||||
end
|
end
|
||||||
|
|
||||||
content = decompress(content, {
|
content = decompress(content, uncompressedSize, {
|
||||||
expected = crcChecksum,
|
expected = crcChecksum,
|
||||||
skip = optionsOrDefault.skipCrcValidation,
|
skip = optionsOrDefault.skipCrcValidation,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue