diff options
author | Jaap Keuter <jaap.keuter@xs4all.nl> | 2012-10-07 09:48:30 +0000 |
---|---|---|
committer | Jaap Keuter <jaap.keuter@xs4all.nl> | 2012-10-07 09:48:30 +0000 |
commit | 4a502ac8647da20e07dd7c22c93f23ab88f24ca8 (patch) | |
tree | 74291ae81af4a5968842033e8ad1979694b28dcd /epan/dissectors/packet-image-jfif.c | |
parent | 5cb8f53f5cc92041742fd7153234b414c22c99c1 (diff) |
From Роман Донченко:
Currently, when Wireshark encounters the first entropy-coded segment in a JPEG
file it stops dissection.
However, the design of the JPEG format allows to find the next marker even if
the entropy-coded segment is not decoded. Thus, a better strategy for Wireshark
would be to skip the entropy-coded segment and continue dissection at the next
marker.
svn path=/trunk/; revision=45363
Diffstat (limited to 'epan/dissectors/packet-image-jfif.c')
-rw-r--r-- | epan/dissectors/packet-image-jfif.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/epan/dissectors/packet-image-jfif.c b/epan/dissectors/packet-image-jfif.c index b1fdcba286..a193f1c36f 100644 --- a/epan/dissectors/packet-image-jfif.c +++ b/epan/dissectors/packet-image-jfif.c @@ -759,8 +759,9 @@ dissect_jfif(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ { proto_tree *subtree = NULL; proto_item *ti = NULL; - guint tvb_len = tvb_reported_length(tvb); - guint32 offset = 0; + gint tvb_len = tvb_reported_length(tvb); + gint32 start_entropy = 0; + gint32 start_fill, start_marker; /* check if we have a full JFIF in tvb */ if (tvb_len < 20) @@ -778,23 +779,48 @@ dissect_jfif(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ ti = proto_tree_add_item(tree, proto_jfif, tvb, 0, -1, ENC_NA); subtree = proto_item_add_subtree(ti, ett_jfif); - proto_tree_add_item(subtree, hf_marker, tvb, 0, 2, ENC_BIG_ENDIAN); } - offset = 2; /* skip MARKER_SOI */ - - /* - * Process the remaining markers and marker segments - */ - while (offset < tvb_len) { + for (; ; ) { const char *str; - const guint16 marker = tvb_get_ntohs(tvb, offset); + guint16 marker; + + start_fill = start_entropy; + + for (; ; ) { + start_fill = tvb_find_guint8(tvb, start_fill, -1, 0xFF); + + if (start_fill == -1 || tvb_len - start_fill == 1 + || tvb_get_guint8(tvb, start_fill + 1) != 0) /* FF 00 is FF escaped */ + break; + + start_fill += 2; + } + + if (start_fill == -1) start_fill = tvb_len; + + if (start_fill != start_entropy) + proto_tree_add_text(subtree, tvb, start_entropy, start_fill - start_entropy, + "Entropy-coded segment (dissection is not yet implemented)"); + + if (start_fill == tvb_len) break; + + start_marker = start_fill; + + while (tvb_get_guint8(tvb, start_marker + 1) == 0xFF) + ++start_marker; + + if (start_marker != start_fill) + proto_tree_add_text(subtree, tvb, start_fill, start_marker - start_fill, + "Fill bytes"); + + marker = tvb_get_ntohs(tvb, start_marker); str = match_strval(marker, vals_marker); if (str) { /* Known marker */ if (marker_has_length(marker)) { /* Marker segment */ /* Length of marker segment = 2 + len */ - const guint16 len = tvb_get_ntohs(tvb, offset + 2); - tvbuff_t *tmp_tvb = tvb_new_subset(tvb, offset, 2 + len, 2 + len); + const guint16 len = tvb_get_ntohs(tvb, start_marker + 2); + tvbuff_t *tmp_tvb = tvb_new_subset(tvb, start_marker, 2 + len, 2 + len); switch (marker) { case MARKER_APP0: process_app0_segment(subtree, tmp_tvb, len, marker, str); @@ -823,27 +849,21 @@ dissect_jfif(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ break; case MARKER_SOS: process_sos_header(subtree, tmp_tvb, len, marker, str); - /* - * TODO - dissect a scan; the scan data is encoded. - */ - proto_tree_add_text(subtree, tvb, offset + 2 + len, -1, - "JFIF dissection stops here (dissection of a scan is not yet implemented)"); - return tvb_len; break; default: process_marker_segment(subtree, tmp_tvb, len, marker, str); break; } - offset += 2 + len; + start_entropy = start_marker + 2 + len; } else { /* Marker but no segment */ /* Length = 2 */ proto_tree_add_item(subtree, hf_marker, - tvb, offset, 2, ENC_BIG_ENDIAN); - offset += 2; + tvb, start_marker, 2, ENC_BIG_ENDIAN); + start_entropy = start_marker + 2; } } else { /* Reserved! */ ti = proto_tree_add_item(subtree, hf_marker, - tvb, offset, 2, ENC_BIG_ENDIAN); + tvb, start_marker, 2, ENC_BIG_ENDIAN); proto_item_append_text(ti, " (Reserved)"); return tvb_len; } |