mp4: handle missing timescale

Avoid various divide-by-zeros when there are durations with no timescale
set. Also fix a rare potential memory leak while I'm here.
This commit is contained in:
Evan Huus 2021-07-22 11:29:27 -04:00 committed by Wireshark GitLab Utility
parent 67d37da79a
commit 05e7c6ac59
1 changed files with 20 additions and 12 deletions

View File

@ -209,13 +209,17 @@ make_fract(guint x)
} }
static inline gchar * static inline gchar *
timescaled_val_to_str(guint64 val) timescaled_val_to_str(wmem_allocator_t *pool, guint64 val)
{ {
nstime_t nstime; nstime_t nstime;
if (mvhd_timescale == 0) {
return wmem_strdup(pool, "no timescale");
}
nstime.secs = val / mvhd_timescale; nstime.secs = val / mvhd_timescale;
nstime.nsecs = (val % mvhd_timescale) * (1000000000UL / mvhd_timescale); nstime.nsecs = (val % mvhd_timescale) * (1000000000UL / mvhd_timescale);
return rel_time_to_str(NULL, &nstime); return rel_time_to_str(pool, &nstime);
} }
static gint static gint
@ -283,10 +287,17 @@ dissect_mp4_mvhd_body(tvbuff_t *tvb, gint offset, gint len _U_,
} else { } else {
duration = tvb_get_ntoh64(tvb , offset); duration = tvb_get_ntoh64(tvb , offset);
} }
if (mvhd_timescale == 0) {
proto_tree_add_uint64_format(tree, hf_mp4_mvhd_duration,
tvb, offset, time_len, duration,
"Duration: no timescale (%" G_GUINT64_FORMAT ")",
duration);
} else {
proto_tree_add_uint64_format(tree, hf_mp4_mvhd_duration, proto_tree_add_uint64_format(tree, hf_mp4_mvhd_duration,
tvb, offset, time_len, duration, tvb, offset, time_len, duration,
"Duration: %f seconds (%" G_GUINT64_FORMAT ")", "Duration: %f seconds (%" G_GUINT64_FORMAT ")",
(double) duration / mvhd_timescale, duration); (double) duration / mvhd_timescale, duration);
}
offset += time_len; offset += time_len;
rate = tvb_get_ntohs(tvb, offset); rate = tvb_get_ntohs(tvb, offset);
@ -738,7 +749,7 @@ dissect_mp4_ctts_body(tvbuff_t *tvb, gint offset, gint len,
static gint static gint
dissect_mp4_elst_body(tvbuff_t *tvb, gint offset, gint len, dissect_mp4_elst_body(tvbuff_t *tvb, gint offset, gint len,
packet_info *pinfo _U_, guint depth _U_, proto_tree *tree) packet_info *pinfo, guint depth _U_, proto_tree *tree)
{ {
guint8 version; guint8 version;
guint32 entry_cnt; guint32 entry_cnt;
@ -771,7 +782,7 @@ dissect_mp4_elst_body(tvbuff_t *tvb, gint offset, gint len,
} else { } else {
segment_duration = tvb_get_ntohl(tvb, offset); segment_duration = tvb_get_ntohl(tvb, offset);
} }
segment_duration_str = timescaled_val_to_str(segment_duration); segment_duration_str = timescaled_val_to_str(pinfo->pool, segment_duration);
proto_tree_add_uint64_format(subtree, hf_mp4_elst_segment_duration, proto_tree_add_uint64_format(subtree, hf_mp4_elst_segment_duration,
tvb, offset, field_length, segment_duration, tvb, offset, field_length, segment_duration,
"Segment duration: %s (%" G_GUINT64_FORMAT ")", "Segment duration: %s (%" G_GUINT64_FORMAT ")",
@ -783,7 +794,7 @@ dissect_mp4_elst_body(tvbuff_t *tvb, gint offset, gint len,
} else { } else {
media_time = tvb_get_ntohl(tvb, offset); media_time = tvb_get_ntohl(tvb, offset);
} }
media_time_str = timescaled_val_to_str(media_time); media_time_str = timescaled_val_to_str(pinfo->pool, media_time);
proto_tree_add_int64_format(subtree, hf_mp4_elst_media_time, proto_tree_add_int64_format(subtree, hf_mp4_elst_media_time,
tvb, offset, field_length, media_time, tvb, offset, field_length, media_time,
"Media time: %s (%" G_GINT64_FORMAT ")", "Media time: %s (%" G_GINT64_FORMAT ")",
@ -801,9 +812,6 @@ dissect_mp4_elst_body(tvbuff_t *tvb, gint offset, gint len,
proto_item_append_text (subtree_item, proto_item_append_text (subtree_item,
" Segment duration: %s; Media time: %s; Media rate: %d.%d", " Segment duration: %s; Media time: %s; Media rate: %d.%d",
segment_duration_str, media_time_str, rate_int, rate_fraction); segment_duration_str, media_time_str, rate_int, rate_fraction);
wmem_free (NULL, segment_duration_str);
wmem_free (NULL, media_time_str);
} }
return len; return len;