Add checks on input/output buffers size for some audio decoders
authorKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 13 Sep 2007 05:59:58 +0000 (05:59 +0000)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 13 Sep 2007 05:59:58 +0000 (05:59 +0000)
Originally committed as revision 10485 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/smacker.c
libavcodec/truespeech.c
libavcodec/ws-snd1.c

index 5d9f5f2c5313dc57181d7905b7ade44e0c1fc83d..e185f4d54f9a0753a5cefdf711d433ea52be77c5 100644 (file)
@@ -590,6 +590,10 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
     }
     stereo = get_bits1(&gb);
     bits = get_bits1(&gb);
+    if ((unp_size << !bits) > *data_size) {
+        av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n");
+        return -1;
+    }
 
     memset(vlc, 0, sizeof(VLC) * 4);
     memset(h, 0, sizeof(HuffContext) * 4);
index a03f2a0ced5d711745e6cd3f35f2f335e26829d9..eafbdf7a01ca2f00d4ad6b12e1c7579b90949bd4 100644 (file)
@@ -333,15 +333,17 @@ static int truespeech_decode_frame(AVCodecContext *avctx,
 {
     TSContext *c = avctx->priv_data;
 
-    int i;
+    int i, j;
     short *samples = data;
     int consumed = 0;
     int16_t out_buf[240];
+    int iterations;
 
     if (!buf_size)
         return 0;
 
-    while (consumed < buf_size) {
+    iterations = FFMIN(buf_size / 32, *data_size / 480);
+    for(j = 0; j < iterations; j++) {
         truespeech_read_frame(c, buf + consumed);
         consumed += 32;
 
@@ -366,7 +368,7 @@ static int truespeech_decode_frame(AVCodecContext *avctx,
 
     *data_size = consumed * 15;
 
-    return buf_size;
+    return consumed;
 }
 
 AVCodec truespeech_decoder = {
index 3624909a30f694612d5449db6d6c1403f9d71c14..a419e3dfb53c05dcb5757b844a39a64273fcccd6 100644 (file)
@@ -62,6 +62,14 @@ static int ws_snd_decode_frame(AVCodecContext *avctx,
     in_size = AV_RL16(&buf[2]);
     buf += 4;
 
+    if (out_size > *data_size) {
+        av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n");
+        return -1;
+    }
+    if (in_size > buf_size) {
+        av_log(avctx, AV_LOG_ERROR, "Frame data is larger than input buffer\n");
+        return -1;
+    }
     if (in_size == out_size) {
         for (i = 0; i < out_size; i++)
             *samples++ = (*buf++ - 0x80) << 8;