summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/file-zip.lua72
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