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 *
timescaled_val_to_str(guint64 val)
timescaled_val_to_str(wmem_allocator_t *pool, guint64 val)
{
nstime_t nstime;
if (mvhd_timescale == 0) {
return wmem_strdup(pool, "no timescale");
}
nstime.secs = val / 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
@ -283,10 +287,17 @@ dissect_mp4_mvhd_body(tvbuff_t *tvb, gint offset, gint len _U_,
} else {
duration = tvb_get_ntoh64(tvb , offset);
}
proto_tree_add_uint64_format(tree, hf_mp4_mvhd_duration,
tvb, offset, time_len, duration,
"Duration: %f seconds (%" G_GUINT64_FORMAT ")",
(double) duration / mvhd_timescale, duration);
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,
tvb, offset, time_len, duration,
"Duration: %f seconds (%" G_GUINT64_FORMAT ")",
(double) duration / mvhd_timescale, duration);
}
offset += time_len;
rate = tvb_get_ntohs(tvb, offset);
@ -738,7 +749,7 @@ dissect_mp4_ctts_body(tvbuff_t *tvb, gint offset, gint len,
static gint
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;
guint32 entry_cnt;
@ -771,7 +782,7 @@ dissect_mp4_elst_body(tvbuff_t *tvb, gint offset, gint len,
} else {
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,
tvb, offset, field_length, segment_duration,
"Segment duration: %s (%" G_GUINT64_FORMAT ")",
@ -783,7 +794,7 @@ dissect_mp4_elst_body(tvbuff_t *tvb, gint offset, gint len,
} else {
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,
tvb, offset, field_length, media_time,
"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,
" Segment duration: %s; Media time: %s; Media rate: %d.%d",
segment_duration_str, media_time_str, rate_int, rate_fraction);
wmem_free (NULL, segment_duration_str);
wmem_free (NULL, media_time_str);
}
return len;