qtdemux: add qt_atom_parse_has_remaining() to avoid overflows with _get_remaining()

This commit is contained in:
Tim-Philipp Müller 2009-08-20 01:39:17 +01:00
parent a16feec38e
commit 9da3ed6491
3 changed files with 30 additions and 23 deletions

View file

@ -38,6 +38,13 @@ qt_atom_parser_get_remaining (QtAtomParser * parser)
return parser->size - parser->byte; return parser->size - parser->byte;
} }
static inline gboolean
qt_atom_parser_has_remaining (QtAtomParser * parser, guint64 min_remaining)
{
return G_LIKELY (parser->size >= min_remaining) &&
G_LIKELY ((parser->size - min_remaining) >= parser->byte);
}
static inline gboolean static inline gboolean
qt_atom_parser_skip (QtAtomParser * parser, guint nbytes) qt_atom_parser_skip (QtAtomParser * parser, guint nbytes)
{ {

View file

@ -3573,7 +3573,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
/* set the sample sizes */ /* set the sample sizes */
if (sample_size == 0) { if (sample_size == 0) {
/* different sizes for each sample */ /* different sizes for each sample */
if (qt_atom_parser_get_remaining (&stsz) < 4 * (n_samples)) if (!qt_atom_parser_has_remaining (&stsz, 4 * n_samples))
goto corrupt_file; goto corrupt_file;
for (i = 0; i < n_samples; i++) { for (i = 0; i < n_samples; i++) {
@ -3592,7 +3592,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
!qt_atom_parser_get_uint32 (&stsc, &n_samples_per_chunk)) !qt_atom_parser_get_uint32 (&stsc, &n_samples_per_chunk))
goto corrupt_file; goto corrupt_file;
if (qt_atom_parser_get_remaining (&stsc) < 12 * n_samples_per_chunk) if (!qt_atom_parser_has_remaining (&stsc, 12 * n_samples_per_chunk))
goto corrupt_file; goto corrupt_file;
index = 0; index = 0;
@ -3665,7 +3665,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
GST_LOG_OBJECT (qtdemux, "%u timestamp blocks", n_sample_times); GST_LOG_OBJECT (qtdemux, "%u timestamp blocks", n_sample_times);
/* make sure there's enough data */ /* make sure there's enough data */
if (qt_atom_parser_get_remaining (&stts) < (n_sample_times * (2 * 4))) if (!qt_atom_parser_has_remaining (&stts, n_sample_times * (2 * 4)))
goto corrupt_file; goto corrupt_file;
timestamp = 0; timestamp = 0;
@ -3732,7 +3732,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
stream->all_keyframe = TRUE; stream->all_keyframe = TRUE;
} else { } else {
/* make sure there's enough data */ /* make sure there's enough data */
if (qt_atom_parser_get_remaining (&stss) < (n_sample_syncs * 4)) if (!qt_atom_parser_has_remaining (&stss, n_sample_syncs * 4))
goto corrupt_file; goto corrupt_file;
for (i = 0; i < n_sample_syncs; i++) { for (i = 0; i < n_sample_syncs; i++) {
/* note that the first sample is index 1, not 0 */ /* note that the first sample is index 1, not 0 */
@ -3755,7 +3755,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
* samples */ * samples */
} else { } else {
/* make sure there's enough data */ /* make sure there's enough data */
if (qt_atom_parser_get_remaining (&stps) < (n_sample_syncs * 4)) if (!qt_atom_parser_has_remaining (&stps, n_sample_syncs * 4))
goto corrupt_file; goto corrupt_file;
for (i = 0; i < n_sample_syncs; i++) { for (i = 0; i < n_sample_syncs; i++) {
/* note that the first sample is index 1, not 0 */ /* note that the first sample is index 1, not 0 */
@ -3802,7 +3802,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
sample_index = 0; sample_index = 0;
timestamp = 0; timestamp = 0;
if (qt_atom_parser_get_remaining (&stsc) < 12 * n_samples_per_chunk) if (!qt_atom_parser_has_remaining (&stsc, 12 * n_samples_per_chunk))
goto corrupt_file; goto corrupt_file;
for (i = 0; i < n_samples_per_chunk; i++) { for (i = 0; i < n_samples_per_chunk; i++) {

View file

@ -36,7 +36,7 @@
gboolean gboolean
qtdemux_dump_mvhd (GstQTDemux * qtdemux, QtAtomParser * data, int depth) qtdemux_dump_mvhd (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
{ {
if (qt_atom_parser_get_remaining (data) < 100) if (!qt_atom_parser_has_remaining (data, 100))
return FALSE; return FALSE;
GST_LOG ("%*s version/flags: %08x", depth, "", GET_UINT32 (data)); GST_LOG ("%*s version/flags: %08x", depth, "", GET_UINT32 (data));
@ -112,7 +112,7 @@ qtdemux_dump_elst (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
if (qt_atom_parser_get_remaining (data) < (num_entries * (4 + 4 + 4))) if (!qt_atom_parser_has_remaining (data, num_entries * (4 + 4 + 4)))
return FALSE; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
@ -163,7 +163,7 @@ qtdemux_dump_hdlr (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
guint32 version, type, subtype, manufacturer; guint32 version, type, subtype, manufacturer;
const gchar *name; const gchar *name;
if (qt_atom_parser_get_remaining (data) < (4 + 4 + 4 + 4 + 4 + 4 + 1)) if (!qt_atom_parser_has_remaining (data, 4 + 4 + 4 + 4 + 4 + 4 + 1))
return FALSE; return FALSE;
version = GET_UINT32 (data); version = GET_UINT32 (data);
@ -189,7 +189,7 @@ qtdemux_dump_hdlr (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
guint len; guint len;
len = qt_atom_parser_get_uint8_unchecked (data); len = qt_atom_parser_get_uint8_unchecked (data);
if (qt_atom_parser_get_remaining (data) >= len) { if (qt_atom_parser_has_remaining (data, len)) {
memcpy (buf, qt_atom_parser_peek_bytes_unchecked (data), len); memcpy (buf, qt_atom_parser_peek_bytes_unchecked (data), len);
buf[len] = '\0'; buf[len] = '\0';
GST_LOG ("%*s name: %s", depth, "", buf); GST_LOG ("%*s name: %s", depth, "", buf);
@ -201,7 +201,7 @@ qtdemux_dump_hdlr (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
gboolean gboolean
qtdemux_dump_vmhd (GstQTDemux * qtdemux, QtAtomParser * data, int depth) qtdemux_dump_vmhd (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
{ {
if (qt_atom_parser_get_remaining (data) < (4 + 4)) if (!qt_atom_parser_has_remaining (data, 4 + 4))
return FALSE; return FALSE;
GST_LOG ("%*s version/flags: %08x", depth, "", GET_UINT32 (data)); GST_LOG ("%*s version/flags: %08x", depth, "", GET_UINT32 (data));
@ -301,7 +301,7 @@ qtdemux_dump_stts (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
if (qt_atom_parser_get_remaining (data) < (num_entries * (4 + 4))) if (!qt_atom_parser_has_remaining (data, num_entries * (4 + 4)))
return FALSE; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
@ -323,7 +323,7 @@ qtdemux_dump_stps (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
if (qt_atom_parser_get_remaining (data) < (num_entries * 4)) if (!qt_atom_parser_has_remaining (data, num_entries * 4))
return FALSE; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
@ -344,7 +344,7 @@ qtdemux_dump_stss (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
if (qt_atom_parser_get_remaining (data) < (num_entries * 4)) if (!qt_atom_parser_has_remaining (data, num_entries * 4))
return FALSE; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
@ -365,7 +365,7 @@ qtdemux_dump_stsc (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
if (qt_atom_parser_get_remaining (data) < (num_entries * (4 + 4 + 4))) if (!qt_atom_parser_has_remaining (data, num_entries * (4 + 4 + 4)))
return FALSE; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
@ -394,8 +394,8 @@ qtdemux_dump_stsz (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
#if 0 #if 0
if (qt_atom_parser_get_remaining (data) < (num_entries * 4))) if (!qt_atom_parser_has_remaining (data, num_entries * 4)))
goto too_short; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
GST_LOG ("%*s sample size: %u", depth, "", GET_UINT32 (data)); GST_LOG ("%*s sample size: %u", depth, "", GET_UINT32 (data));
} }
@ -416,7 +416,7 @@ qtdemux_dump_stco (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
if (qt_atom_parser_get_remaining (data) < (num_entries * 4)) if (!qt_atom_parser_has_remaining (data, num_entries * 4))
return FALSE; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
@ -437,7 +437,7 @@ qtdemux_dump_ctts (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
if (qt_atom_parser_get_remaining (data) < (num_entries * (4 + 4))) if (!qt_atom_parser_has_remaining (data, num_entries * (4 + 4)))
return FALSE; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
@ -460,7 +460,7 @@ qtdemux_dump_co64 (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags);
GST_LOG ("%*s n entries: %d", depth, "", num_entries); GST_LOG ("%*s n entries: %d", depth, "", num_entries);
if (qt_atom_parser_get_remaining (data) < (num_entries * 8)) if (!qt_atom_parser_has_remaining (data, num_entries * 8))
return FALSE; return FALSE;
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
@ -473,7 +473,7 @@ qtdemux_dump_co64 (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
gboolean gboolean
qtdemux_dump_dcom (GstQTDemux * qtdemux, QtAtomParser * data, int depth) qtdemux_dump_dcom (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
{ {
if (qt_atom_parser_get_remaining (data) < 4) if (!qt_atom_parser_has_remaining (data, 4))
return FALSE; return FALSE;
GST_LOG ("%*s compression type: %" GST_FOURCC_FORMAT, depth, "", GST_LOG ("%*s compression type: %" GST_FOURCC_FORMAT, depth, "",
@ -484,7 +484,7 @@ qtdemux_dump_dcom (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
gboolean gboolean
qtdemux_dump_cmvd (GstQTDemux * qtdemux, QtAtomParser * data, int depth) qtdemux_dump_cmvd (GstQTDemux * qtdemux, QtAtomParser * data, int depth)
{ {
if (qt_atom_parser_get_remaining (data) < 4) if (!qt_atom_parser_has_remaining (data, 4))
return FALSE; return FALSE;
GST_LOG ("%*s length: %d", depth, "", GET_UINT32 (data)); GST_LOG ("%*s length: %d", depth, "", GET_UINT32 (data));
@ -508,7 +508,7 @@ static gboolean
qtdemux_node_dump_foreach (GNode * node, gpointer qtdemux) qtdemux_node_dump_foreach (GNode * node, gpointer qtdemux)
{ {
QtAtomParser parser; QtAtomParser parser;
guint8 *buffer = (guint8 *) node->data; guint8 *buffer = (guint8 *) node->data; // FIXME: move to byte reader
guint32 node_length; guint32 node_length;
guint32 fourcc; guint32 fourcc;
const QtNodeType *type; const QtNodeType *type;