Report malformed zip headers instead of raising
A central directory record or local header cut short of its length fields made zip_entries and zip_data do arithmetic on nil, so the parse raised where every other failure returns nil, err. Bound both against the buffer first. A pax record claiming a zero length no longer spins forever.
This commit is contained in:
@@ -140,6 +140,11 @@ local function zip_entries(buf)
|
||||
if u32(buf, pos) ~= CD_SIG then
|
||||
return nil, 'malformed central directory'
|
||||
end
|
||||
-- The fixed 46-byte header has to be there in full, otherwise the fields
|
||||
-- read below are nil and the parse blows up instead of reporting.
|
||||
if pos + 45 > #buf then
|
||||
return nil, 'truncated central directory'
|
||||
end
|
||||
local namelen = u16(buf, pos + 28)
|
||||
local entry = {
|
||||
version_made_by = u16(buf, pos + 4),
|
||||
@@ -166,6 +171,9 @@ local function zip_data(buf, entry)
|
||||
if u32(buf, lho) ~= LOCAL_SIG then
|
||||
return reject(entry.name, 'invalid local header signature')
|
||||
end
|
||||
if lho + 29 > #buf then
|
||||
return reject(entry.name, 'truncated local header')
|
||||
end
|
||||
local start = lho + 30 + u16(buf, lho + 26) + u16(buf, lho + 28)
|
||||
|
||||
local data
|
||||
@@ -262,6 +270,10 @@ local function pax_records(block)
|
||||
break
|
||||
end
|
||||
len = tonumber(len)
|
||||
-- A zero length would leave pos where it is and spin forever.
|
||||
if len < 1 then
|
||||
break
|
||||
end
|
||||
local record = block:sub(rest, pos + len - 2)
|
||||
local key, value = record:match('^([^=]+)=(.*)$')
|
||||
if key then
|
||||
|
||||
Reference in New Issue
Block a user