]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - aacdec.c
aacdec: Do not try to feed invalid buffers to libfaad
[paraslash.git] / aacdec.c
index 5e5320065baf9f97b6e2706a3a3de596368fa039..3963bbc77edbc740fab040afd5a4d196e57d8b15 100644 (file)
--- a/aacdec.c
+++ b/aacdec.c
  *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  */
 
+/*
+ * based in parts on libfaad, Copyright (C) 2003-2005 M. Bakker,
+ * Ahead Software AG
+ */
+
 /** \file aacdec.c paraslash's mp3 decoder */
 
 #include "para.h"
@@ -44,13 +49,14 @@ struct private_mp4dec_data {
        mp4AudioSpecificConfig mp4ASC;
 
        int initialized;
-       char *inbuf;
+       int decoder_length;
+       unsigned char *inbuf;
        int inbuf_len;
        int consumed;
        long unsigned consumed_total;
 
-       int noffsets;
-       int *offset;
+       unsigned noffsets;
+       unsigned *offset;
        int offset_pos;
 };
 
@@ -73,7 +79,7 @@ static int read_mp4_descr_length(struct private_mp4dec_data *padd)
 static int find_esds(struct private_mp4dec_data *padd)
 {
        for (; padd->consumed < padd->inbuf_len; padd->consumed++) {
-               char *p = padd->inbuf + padd->consumed;
+               unsigned char *p = padd->inbuf + padd->consumed;
                int decoder_length;
 
                if (p[0] != 'e' || p[1] != 's' || p[2] != 'd' || p[3] != 's')
@@ -135,7 +141,7 @@ static int find_stco(struct private_mp4dec_data *padd)
        int ret;
 
        for (; padd->consumed < padd->inbuf_len; padd->consumed++) {
-               char *p = padd->inbuf + padd->consumed;
+               unsigned char *p = padd->inbuf + padd->consumed;
 
                if (p[0] != 's' || p[1] != 't' || p[2] != 'c' || p[3] != 'o')
                        continue;
@@ -163,20 +169,26 @@ static ssize_t mp4dec(char *inbuffer, size_t len, struct filter_node *fn)
        if (len < 1000 && !*fci->eof)
                return 0;
        padd->consumed = 0;
-       padd->inbuf = inbuffer;
+       padd->inbuf = (unsigned char*)inbuffer;
        padd->inbuf_len = len;
 
        if (!padd->initialized) {
-               ret = find_esds(padd);
-               if (ret < 0)
-                       goto out;
-
-               p = inbuffer + padd->consumed;
-               ret = E_AACDEC_INIT;
-               if (NeAACDecInit2(padd->decoder, p, ret, &rate, &channels) < 0) {
-                       PARA_INFO_LOG("header not found, consumed: %d\n",
-                               padd->consumed);
-                       goto out;
+               padd->decoder_length = find_esds(padd);
+               if (padd->decoder_length < 0) {
+                       ret = NeAACDecInit(padd->decoder, padd->inbuf,
+                               padd->inbuf_len, &rate, &channels);
+                       if (ret < 0) {
+                               ret = E_AACDEC_INIT;
+                               goto out;
+                       }
+                       padd->consumed = ret;
+               } else {
+                       p = padd->inbuf + padd->consumed;
+                       ret = E_AACDEC_INIT;
+                       if (NeAACDecInit2(padd->decoder, p,
+                                       padd->decoder_length, &rate,
+                                       &channels) < 0)
+                               goto out;
                }
                fci->samplerate = rate;
                fci->channels = channels;
@@ -184,35 +196,48 @@ static ssize_t mp4dec(char *inbuffer, size_t len, struct filter_node *fn)
                        fci->channels);
                padd->initialized = 1;
        }
-       padd->consumed = 0;
-       if (!padd->offset_pos) {
+       if (padd->decoder_length > 0) {
+               padd->consumed = 0;
+               if (!padd->offset_pos) {
+                       ret = len;
+                       if (find_stco(padd) < 0)
+                               goto out;
+               }
+               if (padd->offset_pos < padd->noffsets) {
+                       fill_offset_table(padd);
+                       ret = padd->consumed;
+                       goto out;
+               }
+//             PARA_INFO_LOG("consumed total: %lu, first_chunk: %d\n",
+//                     padd->consumed_total, padd->offset[0]);
                ret = len;
-               if (find_stco(padd) < 0)
+               if (padd->consumed_total + len < padd->offset[0])
                        goto out;
+               if (padd->consumed_total < padd->offset[0])
+                       padd->consumed = padd->offset[0] - padd->consumed_total;
        }
-       if (padd->offset_pos < padd->noffsets) {
-               fill_offset_table(padd);
-               ret = padd->consumed;
-               goto out;
+       p = memchr(padd->inbuf + padd->consumed, 0x21,
+               padd->inbuf_len - padd->consumed);
+       if (!p) {
+               padd->consumed = padd->inbuf_len;
+               goto success;
+       }
+       if (p != padd->inbuf + padd->consumed) {
+               int skip = p - padd->inbuf + padd->consumed;
+               PARA_DEBUG_LOG("skipping %d bytes in inbuffer\n", skip);
+               padd->consumed += skip;
        }
-       PARA_INFO_LOG("consumed total: %lu, first_chunk: %d\n",
-               padd->consumed_total, padd->offset[0]);
-       ret = len;
-       if (padd->consumed_total + len < padd->offset[0])
-               goto out;
-       if (padd->consumed_total < padd->offset[0])
-               padd->consumed = padd->offset[0] - padd->consumed_total;
-       p = padd->inbuf + padd->consumed;
        outbuffer = NeAACDecDecode(padd->decoder, &padd->frame_info, p,
                len - padd->consumed);
-       PARA_INFO_LOG("frame_error: %d, consumed: %lu + %d + %lu\n",
-               padd->frame_info.error, padd->consumed_total,
-               padd->consumed, padd->frame_info.bytesconsumed);
        ret = -E_AAC_DECODE;
        if (padd->frame_info.error != 0) {
+               PARA_ERROR_LOG("frame_error: %d, consumed: %lu + %d + %lu\n",
+                       padd->frame_info.error, padd->consumed_total,
+                       padd->consumed, padd->frame_info.bytesconsumed);
                PARA_ERROR_LOG("%s\n", NeAACDecGetErrorMessage(
                        padd->frame_info.error));
-               goto out;
+               padd->consumed++; /* catch 21 */
+               goto success;
        }
        padd->consumed += padd->frame_info.bytesconsumed;
        ret = padd->consumed;
@@ -224,6 +249,7 @@ static ssize_t mp4dec(char *inbuffer, size_t len, struct filter_node *fn)
                fn->buf[fn->loaded++] = s[i] & 0xff;
                fn->buf[fn->loaded++] = (s[i] >> 8) & 0xff;
        }
+success:
        ret = padd->consumed;
 out:
        if (ret > 0)