wavparse: Fix parsing of adtl chunks
authorSebastian Dröge <sebastian@centricular.com>
Fri, 12 Sep 2014 12:06:50 +0000 (15:06 +0300)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 12 Sep 2014 12:08:23 +0000 (15:08 +0300)
We have to skip 12 bytes of data for the chunk, and the data size
passed to the sub-chunk parsing functions should have 4 bytes less
than the data size.

Also when parsing the sub-chunks, check if we actually have enough
data to read instead of just crashing.

https://bugzilla.gnome.org/show_bug.cgi?id=736266

gst/wavparse/gstwavparse.c

index ef1f904..a57037e 100644 (file)
@@ -889,6 +889,12 @@ gst_wavparse_adtl_chunk (GstWavParse * wav, const guint8 * data, guint32 size)
   while (size >= 8) {
     ltag = GST_READ_UINT32_LE (data + offset);
     lsize = GST_READ_UINT32_LE (data + offset + 4);
+
+    if (lsize + 8 > size) {
+      GST_WARNING_OBJECT (wav, "Invalid adtl size: %u + 8 > %u", lsize, size);
+      return FALSE;
+    }
+
     switch (ltag) {
       case GST_RIFF_TAG_labl:
         gst_wavparse_labl_chunk (wav, data + offset, size);
@@ -1470,13 +1476,14 @@ gst_wavparse_stream_headers (GstWavParse * wav)
             break;
           }
           case GST_RIFF_LIST_adtl:{
-            const gint data_size = size;
+            const gint data_size = size - 4;
 
             GST_INFO_OBJECT (wav, "Have 'adtl' LIST, size %u", data_size);
             if (wav->streaming) {
               const guint8 *data = NULL;
 
               gst_adapter_flush (wav->adapter, 12);
+              wav->offset += 12;
               data = gst_adapter_map (wav->adapter, data_size);
               gst_wavparse_adtl_chunk (wav, data, data_size);
               gst_adapter_unmap (wav->adapter);
@@ -1485,8 +1492,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
 
               gst_buffer_unref (buf);
               buf = NULL;
+              wav->offset += 12;
               if ((res =
-                      gst_pad_pull_range (wav->sinkpad, wav->offset + 12,
+                      gst_pad_pull_range (wav->sinkpad, wav->offset,
                           data_size, &buf)) != GST_FLOW_OK)
                 goto header_read_error;
               gst_buffer_map (buf, &map, GST_MAP_READ);