forked from osmocom/wireshark
jpeg: add support for dissecting inline IFD values
In many cases, the "value offset" is actually the value itself. Handle those cases correctly.
This commit is contained in:
parent
cc91fd51ff
commit
e116110f0c
|
@ -267,17 +267,28 @@ static const value_string vals_exif_tags[] = {
|
|||
{ 0x0000, NULL }
|
||||
};
|
||||
|
||||
static const value_string vals_exif_types[] = {
|
||||
{ 0x0001, "BYTE" },
|
||||
{ 0x0002, "ASCII" },
|
||||
{ 0x0003, "SHORT" },
|
||||
{ 0x0004, "LONG" },
|
||||
{ 0x0005, "RATIONAL" },
|
||||
enum {
|
||||
EXIF_TYPE_BYTE = 0x0001,
|
||||
EXIF_TYPE_ASCII = 0x0002,
|
||||
EXIF_TYPE_SHORT = 0x0003,
|
||||
EXIF_TYPE_LONG = 0x0004,
|
||||
EXIF_TYPE_RATIONAL = 0x0005,
|
||||
/* 0x0006 */
|
||||
{ 0x0007, "UNDEFINED" },
|
||||
EXIF_TYPE_UNDEFINED = 0x0007,
|
||||
/* 0x0008 */
|
||||
{ 0x0009, "SLONG" },
|
||||
{ 0x000A, "SRATIONAL" },
|
||||
EXIF_TYPE_SLONG = 0x0009,
|
||||
EXIF_TYPE_SRATIONAL = 0x000A,
|
||||
};
|
||||
|
||||
static const value_string vals_exif_types[] = {
|
||||
{ EXIF_TYPE_BYTE, "BYTE" },
|
||||
{ EXIF_TYPE_ASCII, "ASCII" },
|
||||
{ EXIF_TYPE_SHORT, "SHORT" },
|
||||
{ EXIF_TYPE_LONG, "LONG" },
|
||||
{ EXIF_TYPE_RATIONAL, "RATIONAL" },
|
||||
{ EXIF_TYPE_UNDEFINED, "UNDEFINED" },
|
||||
{ EXIF_TYPE_SLONG, "SLONG" },
|
||||
{ EXIF_TYPE_SRATIONAL, "SRATIONAL" },
|
||||
|
||||
{ 0x0000, NULL }
|
||||
};
|
||||
|
@ -343,6 +354,12 @@ static gint hf_ifd_tag = -1;
|
|||
static gint hf_ifd_type = -1;
|
||||
static gint hf_ifd_count = -1;
|
||||
static gint hf_ifd_offset = -1;
|
||||
static gint hf_ifd_value_byte = -1;
|
||||
static gint hf_ifd_value_ascii = -1;
|
||||
static gint hf_ifd_value_short = -1;
|
||||
static gint hf_ifd_value_long = -1;
|
||||
static gint hf_ifd_value_undefined = -1;
|
||||
static gint hf_ifd_value_slong = -1;
|
||||
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
|
@ -676,13 +693,48 @@ process_app1_segment(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint3
|
|||
proto_tree_add_item(subtree_ifd, hf_ifd_num_fields, tvb, offset, 2, encoding);
|
||||
offset += 2;
|
||||
while (num_fields-- > 0) {
|
||||
guint32 field_type, value_count, value_size;
|
||||
gint value_hf;
|
||||
|
||||
proto_tree_add_item(subtree_ifd, hf_ifd_tag, tvb, offset, 2, encoding);
|
||||
offset += 2;
|
||||
proto_tree_add_item(subtree_ifd, hf_ifd_type, tvb, offset, 2, encoding);
|
||||
proto_tree_add_item_ret_uint(subtree_ifd, hf_ifd_type, tvb, offset, 2, encoding, &field_type);
|
||||
offset += 2;
|
||||
proto_tree_add_item(subtree_ifd, hf_ifd_count, tvb, offset, 4, encoding);
|
||||
proto_tree_add_item_ret_uint(subtree_ifd, hf_ifd_count, tvb, offset, 4, encoding, &value_count);
|
||||
offset += 4;
|
||||
proto_tree_add_item(subtree_ifd, hf_ifd_offset, tvb, offset, 4, encoding);
|
||||
|
||||
switch (field_type) {
|
||||
case EXIF_TYPE_BYTE:
|
||||
value_size = 1; value_hf = hf_ifd_value_byte; break;
|
||||
case EXIF_TYPE_ASCII:
|
||||
value_size = 1; value_hf = hf_ifd_value_ascii; break;
|
||||
case EXIF_TYPE_SHORT:
|
||||
value_size = 2; value_hf = hf_ifd_value_short; break;
|
||||
case EXIF_TYPE_LONG:
|
||||
value_size = 4; value_hf = hf_ifd_value_long; break;
|
||||
case EXIF_TYPE_UNDEFINED:
|
||||
value_size = 1; value_hf = hf_ifd_value_undefined; break;
|
||||
case EXIF_TYPE_SLONG:
|
||||
value_size = 4; value_hf = hf_ifd_value_slong; break;
|
||||
/* We don't need special handling for RATIONAL/SRATIONAL,
|
||||
since they never fit into the offset field,
|
||||
so the default branch works for them. */
|
||||
default:
|
||||
value_size = 0; break;
|
||||
}
|
||||
|
||||
if (value_size == 0 || 4 / value_size < value_count) {
|
||||
proto_tree_add_item(subtree_ifd, hf_ifd_offset, tvb, offset, 4, encoding);
|
||||
} else {
|
||||
/* The value(s) are small enough to fit directly in the offset field. */
|
||||
|
||||
if (value_hf == hf_ifd_value_ascii || value_hf == hf_ifd_value_undefined)
|
||||
proto_tree_add_item(subtree_ifd, value_hf, tvb, offset, value_count, ENC_NA);
|
||||
else
|
||||
for (guint32 i = 0; i < value_count; ++i)
|
||||
proto_tree_add_item(subtree_ifd, value_hf, tvb,
|
||||
offset + i * value_size, value_size, encoding);
|
||||
}
|
||||
offset += 4;
|
||||
}
|
||||
/*
|
||||
|
@ -1282,6 +1334,54 @@ proto_register_jfif(void)
|
|||
HFILL
|
||||
}
|
||||
},
|
||||
{ &hf_ifd_value_byte,
|
||||
{ "Value",
|
||||
"image-jfif.ifd.value_byte",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0,
|
||||
NULL,
|
||||
HFILL
|
||||
}
|
||||
},
|
||||
{ &hf_ifd_value_ascii,
|
||||
{ "Value",
|
||||
"image-jfif.ifd.value_ascii",
|
||||
FT_STRING, BASE_NONE, NULL, 0x0,
|
||||
NULL,
|
||||
HFILL
|
||||
}
|
||||
},
|
||||
{ &hf_ifd_value_short,
|
||||
{ "Value",
|
||||
"image-jfif.ifd.value_short",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
NULL,
|
||||
HFILL
|
||||
}
|
||||
},
|
||||
{ &hf_ifd_value_long,
|
||||
{ "Value",
|
||||
"image-jfif.ifd.value_long",
|
||||
FT_UINT32, BASE_DEC, NULL, 0x0,
|
||||
NULL,
|
||||
HFILL
|
||||
}
|
||||
},
|
||||
{ &hf_ifd_value_undefined,
|
||||
{ "Value (raw)",
|
||||
"image-jfif.ifd.value_undefined",
|
||||
FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
NULL,
|
||||
HFILL
|
||||
}
|
||||
},
|
||||
{ &hf_ifd_value_slong,
|
||||
{ "Value",
|
||||
"image-jfif.ifd.value_slong",
|
||||
FT_INT32, BASE_DEC, NULL, 0x0,
|
||||
NULL,
|
||||
HFILL
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/* Setup protocol subtree array */
|
||||
|
|
Loading…
Reference in New Issue