diff options
Diffstat (limited to 'lua/file-zip.lua')
-rw-r--r-- | lua/file-zip.lua | 72 |
1 files changed, 60 insertions, 12 deletions
diff --git a/lua/file-zip.lua b/lua/file-zip.lua index 241142c..ee23087 100644 --- a/lua/file-zip.lua +++ b/lua/file-zip.lua @@ -43,7 +43,11 @@ make_fields("zip_archive", { entry = { _ = {ProtoField.none, "File entry"}, version = {ProtoField.uint16, base.DEC}, - flag = {ProtoField.uint16, base.HEX}, + flag = { + _ = {ProtoField.uint16, "General purpose bit flag", base.HEX}, + -- TODO fi wslua documentation, it is wrong. + has_data_desc = {ProtoField.bool, 16, nil, 0x0008, "Whether data descriptor is present"}, + }, comp_method = {ProtoField.uint16, base.HEX}, lastmod_time = {ProtoField.uint16, base.HEX}, lastmod_date = {ProtoField.uint16, base.HEX}, @@ -55,6 +59,12 @@ make_fields("zip_archive", { filename = {ProtoField.string}, extra = {ProtoField.bytes}, data = {ProtoField.bytes}, + data_desc = { + _ = {ProtoField.none, "Data descriptor"}, + crc32 = {ProtoField.uint32, base.HEX}, + size_comp = {ProtoField.uint32, base.DEC}, + size_uncomp = {ProtoField.uint32, base.DEC}, + }, }, cd = { _ = {ProtoField.none, "Central Directory Record"}, @@ -90,9 +100,6 @@ make_fields("zip_archive", { }, }, hf, proto_zip.fields) -local function dissect_entry(tvb, pinfo, tree) -end - local function dissect_one(tvb, offset, pinfo, tree) local orig_offset = offset local magic = tvb(offset, 4):le_int() @@ -101,7 +108,9 @@ local function dissect_one(tvb, offset, pinfo, tree) -- header subtree:add_le(hf.signature, tvb(offset, 4)) subtree:add_le(hf.entry.version, tvb(offset + 4, 2)) - subtree:add_le(hf.entry.flag, tvb(offset + 6, 2)) + local flgtree = subtree:add_le(hf.entry.flag._, tvb(offset + 6, 2)) + -- TODO why does flag.has_data_desc segfault if tvb is not given? + flgtree:add_le(hf.entry.flag.has_data_desc, tvb(offset + 6, 2)) subtree:add_le(hf.entry.comp_method, tvb(offset + 8, 2)) subtree:add_le(hf.entry.lastmod_time, tvb(offset + 10, 2)) subtree:add_le(hf.entry.lastmod_date, tvb(offset + 12, 2)) @@ -110,19 +119,56 @@ local function dissect_one(tvb, offset, pinfo, tree) subtree:add_le(hf.entry.size_uncomp, tvb(offset + 22, 4)) subtree:add_le(hf.entry.filename_len, tvb(offset + 26, 2)) subtree:add_le(hf.entry.extra_len, tvb(offset + 28, 2)) + local flag = tvb(offset + 6, 2):le_uint() local data_len = tvb(offset + 18, 2):le_uint() local filename_len = tvb(offset + 26, 2):le_uint() local extra_len = tvb(offset + 28, 2):le_uint() + -- Optional data descriptor follows data if GP flag bit 3 (0x8) is set + --[[ This is wrong, cannot know the location of dd, have to query CD first + local ddlen + if bit.band(flag, 8) ~= 0 then + local dd_offset = offset + 30 + filename_len + extra_len + data_len + if tvb(dd_offset, 4):le_uint() == 0x08074b50 then + -- Optional data descriptor signature... WTF, why?! + dd_offset = dd_offset + 4 + ddlen = 16 + else + ddlen = 12 + end + subtree:add_le(hf.entry.data_desc.size_comp, tvb(dd_offset + 4, 4)) + --data_len = tvb(dd_offset + 4, 4):le_uint() + end + --]] + -- skip header offset = offset + 30 subtree:add(hf.entry.filename, tvb(offset, filename_len)) subtree:append_text(": " .. tvb(offset, filename_len):string()) offset = offset + filename_len - subtree:add(hf.entry.extra, tvb(offset, extra_len)) - offset = offset + extra_len - subtree:add(hf.entry.data, tvb(offset, data_len)) - offset = offset + data_len + if extra_len > 0 then + subtree:add(hf.entry.extra, tvb(offset, extra_len)) + offset = offset + extra_len + end + if data_len > 0 then + subtree:add(hf.entry.data, tvb(offset, data_len)) + offset = offset + data_len + end + --[[ This does need really work.. + -- Optional data descriptor header + if ddlen then + local dd_offset = offset + local ddtree = subtree:add_le(hf.entry.data_desc._, tvb(dd_offset, ddlen)) + if ddlen == 16 then + ddtree:add_le(hf.signature, tvb(dd_offset, 4)) + dd_offset = dd_offset + 4 + end + ddtree:add_le(hf.entry.data_desc.crc32, tvb(dd_offset, 4)) + ddtree:add_le(hf.entry.data_desc.size_comp, tvb(dd_offset + 4, 4)) + ddtree:add_le(hf.entry.data_desc.size_uncomp, tvb(dd_offset + 8, 4)) + offset = offset + ddlen + end + --]] subtree:set_len(offset - orig_offset) return offset @@ -154,8 +200,10 @@ local function dissect_one(tvb, offset, pinfo, tree) subtree:add(hf.cd.filename, tvb(offset, filename_len)) subtree:append_text(": " .. tvb(offset, filename_len):string()) offset = offset + filename_len - subtree:add(hf.cd.extra, tvb(offset, extra_len)) - offset = offset + extra_len + if extra_len > 0 then + subtree:add(hf.cd.extra, tvb(offset, extra_len)) + offset = offset + extra_len + end if comment_len > 0 then subtree:add(hf.cd.comment, tvb(offset, comment_len)) offset = offset + comment_len @@ -192,7 +240,7 @@ function proto_zip.dissector(tvb, pinfo, tree) --pinfo.cols.info = "" local next_offset = 0 - while next_offset < tvb:len() do + while next_offset and next_offset < tvb:len() do next_offset = dissect_one(tvb, next_offset, pinfo, tree) end return next_offset |