Do not crash for illegal sample size, fixes issue 2502.
authorDaniel Kang <daniel.d.kang@gmail.com>
Tue, 11 Jan 2011 14:08:45 +0000 (14:08 +0000)
committerCarl Eugen Hoyos <cehoyos@rainbow.studorg.tuwien.ac.at>
Tue, 11 Jan 2011 14:08:45 +0000 (14:08 +0000)
Patch by Daniel Kang, daniel.d.kang at gmail

Originally committed as revision 26309 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/pcm.c
libavformat/vocdec.c

index b6b49dc..533e834 100644 (file)
@@ -292,6 +292,11 @@ static int pcm_decode_frame(AVCodecContext *avctx,
         /* we process 40-bit blocks per channel for LXF */
         sample_size = 5;
 
+    if (sample_size == 0) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid sample_size\n");
+        return AVERROR(EINVAL);
+    }
+
     n = avctx->channels * sample_size;
 
     if(n && buf_size % n){
index 909520c..aa69dd2 100644 (file)
@@ -68,7 +68,7 @@ voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
     AVCodecContext *dec = st->codec;
     ByteIOContext *pb = s->pb;
     VocType type;
-    int size;
+    int size, tmp_codec;
     int sample_rate = 0;
     int channels = 1;
 
@@ -90,7 +90,11 @@ voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
             if (sample_rate)
                 dec->sample_rate = sample_rate;
             dec->channels = channels;
-            dec->codec_id = ff_codec_get_id(ff_voc_codec_tags, get_byte(pb));
+            tmp_codec = ff_codec_get_id(ff_voc_codec_tags, get_byte(pb));
+            if (dec->codec_id == CODEC_ID_NONE)
+                dec->codec_id = tmp_codec;
+            else if (dec->codec_id != tmp_codec)
+                av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n");
             dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id);
             voc->remaining_size -= 2;
             max_size -= 2;
@@ -113,7 +117,11 @@ voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
             dec->sample_rate = get_le32(pb);
             dec->bits_per_coded_sample = get_byte(pb);
             dec->channels = get_byte(pb);
-            dec->codec_id = ff_codec_get_id(ff_voc_codec_tags, get_le16(pb));
+            tmp_codec = ff_codec_get_id(ff_voc_codec_tags, get_byte(pb));
+            if (dec->codec_id == CODEC_ID_NONE)
+                dec->codec_id = tmp_codec;
+            else if (dec->codec_id != tmp_codec)
+                av_log(s, AV_LOG_WARNING, "Ignoring mid-stream change in audio codec\n");
             url_fskip(pb, 4);
             voc->remaining_size -= 12;
             max_size -= 12;
@@ -125,6 +133,10 @@ voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
             voc->remaining_size = 0;
             break;
         }
+        if (dec->codec_id == CODEC_ID_NONE) {
+            av_log(s, AV_LOG_ERROR, "Invalid codec_id\n");
+            if (s->audio_codec_id == CODEC_ID_NONE) return AVERROR(EINVAL);
+        }
     }
 
     dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample;