From f7c033f4ec8774ad194e8605388c597bee729e36 Mon Sep 17 00:00:00 2001 From: Heekyoung Seo Date: Fri, 9 Dec 2016 20:27:53 +0900 Subject: [PATCH] qtdemux: Check node length of video sample description Add check for node length of video sample description and its fields and for the XiTh atom. Also unify the code a bit. https://bugzilla.gnome.org/show_bug.cgi?id=775794 --- gst/isomp4/qtdemux.c | 105 +++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 64 deletions(-) diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c index 5651a2b61b..3ae6a2ecda 100644 --- a/gst/isomp4/qtdemux.c +++ b/gst/isomp4/qtdemux.c @@ -7227,77 +7227,53 @@ qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, const guint8 * buffer, case FOURCC_ap4h: case FOURCC_xvid: case FOURCC_XVID: + case FOURCC_H264: + case FOURCC_avc1: + case FOURCC_avc3: + case FOURCC_H265: + case FOURCC_hvc1: + case FOURCC_hev1: + case FOURCC_mjp2: + case FOURCC_encv: { - const guint8 *buf; guint32 version; - int tlen; + guint32 str_len; /* codec_data is contained inside these atoms, which all have * the same format. */ + /* video sample description size is 86 bytes without extension. + * node_length have to be bigger than 86 bytes because video sample + * description can include extenstions such as esds, fiel, glbl, etc. */ + if (node_length < 86) { + GST_WARNING_OBJECT (qtdemux, "%" GST_FOURCC_FORMAT + " sample description length too short (%u < 86)", + GST_FOURCC_ARGS (fourcc), node_length); + break; + } GST_DEBUG_OBJECT (qtdemux, "parsing in %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc)); + + /* version (2 bytes) : this is set to 0, unless a compressor has changed + * its data format. + * revision level (2 bytes) : must be set to 0. */ version = QT_UINT32 (buffer + 16); GST_DEBUG_OBJECT (qtdemux, "version %08x", version); - if (1 || version == 0x00000000) { - buf = buffer + 0x32; - /* FIXME Quicktime uses PASCAL string while - * the iso format uses C strings. Check the file - * type before attempting to parse the string here. */ - tlen = QT_UINT8 (buf); - GST_DEBUG_OBJECT (qtdemux, "tlen = %d", tlen); - buf++; - GST_DEBUG_OBJECT (qtdemux, "string = %.*s", tlen, (char *) buf); - /* the string has a reserved space of 32 bytes so skip - * the remaining 31 */ - buf += 31; - buf += 4; /* and 4 bytes reserved */ + /* compressor name : PASCAL string and informative purposes + * first byte : the number of bytes to be displayed. + * it has to be less than 32 because it is reserved + * space of 32 bytes total including itself. */ + str_len = QT_UINT8 (buffer + 50); + if (str_len < 32) + GST_DEBUG_OBJECT (qtdemux, "compressorname = %.*s", str_len, + (char *) buffer + 51); + else + GST_WARNING_OBJECT (qtdemux, + "compressorname length too big (%u > 31)", str_len); - GST_MEMDUMP_OBJECT (qtdemux, "mp4v", buf, end - buf); - - qtdemux_parse_container (qtdemux, node, buf, end); - } - break; - } - case FOURCC_H264: - { - GST_MEMDUMP_OBJECT (qtdemux, "H264", buffer, end - buffer); - qtdemux_parse_container (qtdemux, node, buffer + 0x56, end); - break; - } - case FOURCC_avc1: - { - GST_MEMDUMP_OBJECT (qtdemux, "avc1", buffer, end - buffer); - qtdemux_parse_container (qtdemux, node, buffer + 0x56, end); - break; - } - case FOURCC_avc3: - { - GST_MEMDUMP_OBJECT (qtdemux, "avc3", buffer, end - buffer); - qtdemux_parse_container (qtdemux, node, buffer + 0x56, end); - break; - } - case FOURCC_H265: - { - GST_MEMDUMP_OBJECT (qtdemux, "H265", buffer, end - buffer); - qtdemux_parse_container (qtdemux, node, buffer + 0x56, end); - break; - } - case FOURCC_hvc1: - { - GST_MEMDUMP_OBJECT (qtdemux, "hvc1", buffer, end - buffer); - qtdemux_parse_container (qtdemux, node, buffer + 0x56, end); - break; - } - case FOURCC_hev1: - { - GST_MEMDUMP_OBJECT (qtdemux, "hev1", buffer, end - buffer); - qtdemux_parse_container (qtdemux, node, buffer + 0x56, end); - break; - } - case FOURCC_mjp2: - { + GST_MEMDUMP_OBJECT (qtdemux, "video sample description", buffer, + end - buffer); qtdemux_parse_container (qtdemux, node, buffer + 86, end); break; } @@ -7319,6 +7295,12 @@ qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, const guint8 * buffer, guint32 version; guint32 offset; + if (length < 16) { + GST_LOG_OBJECT (qtdemux, "skipping small %" GST_FOURCC_FORMAT " box", + GST_FOURCC_ARGS (fourcc)); + break; + } + version = QT_UINT32 (buffer + 12); GST_DEBUG_OBJECT (qtdemux, "parsing XiTh atom version 0x%08x", version); @@ -7345,11 +7327,6 @@ qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, const guint8 * buffer, qtdemux_parse_uuid (qtdemux, buffer, end - buffer); break; } - case FOURCC_encv: - { - qtdemux_parse_container (qtdemux, node, buffer + 86, end); - break; - } case FOURCC_enca: { qtdemux_parse_container (qtdemux, node, buffer + 36, end);