oma: Validate sample rates
[ffmpeg.git] / libavformat / omadec.c
index 810e970..0603aa2 100644 (file)
  * CODEC SUPPORT: Only ATRAC3 codec is currently supported!
  */
 
+#include "libavutil/channel_layout.h"
 #include "avformat.h"
 #include "internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/des.h"
 #include "oma.h"
 #include "pcm.h"
-#include "riff.h"
 #include "id3v2.h"
 
 
@@ -140,7 +140,7 @@ static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val)
     return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0;
 }
 
-static int nprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *n_val)
+static int nprobe(AVFormatContext *s, uint8_t *enc_header, int size, const uint8_t *n_val)
 {
     OMAContext *oc = s->priv_data;
     uint32_t pos, taglen, datalen;
@@ -159,6 +159,9 @@ static int nprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *n_val)
     taglen = AV_RB32(&enc_header[pos+32]);
     datalen = AV_RB32(&enc_header[pos+36]) >> 4;
 
+    if(taglen + (((uint64_t)datalen)<<4) + 44 > size)
+        return -1;
+
     pos += 44 + taglen;
 
     av_des_init(&av_des, n_val, 192, 1);
@@ -229,14 +232,14 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
     }
     if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
         rprobe(s, gdata, oc->r_val) < 0 &&
-        nprobe(s, gdata, oc->n_val) < 0) {
+        nprobe(s, gdata, geob->datasize, oc->n_val) < 0) {
         int i;
         for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) {
             uint8_t buf[16];
             AV_WL64(buf, leaf_table[i]);
             AV_WL64(&buf[8], leaf_table[i+1]);
             kset(s, buf, buf, 16);
-            if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, oc->n_val))
+            if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, geob->datasize, oc->n_val))
                 break;
         }
         if (i >= sizeof(leaf_table)) {
@@ -301,14 +304,18 @@ static int oma_read_header(AVFormatContext *s)
 
     switch (buf[32]) {
         case OMA_CODECID_ATRAC3:
-            samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100;
+            samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
+            if (!samplerate) {
+                av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
+                return AVERROR_INVALIDDATA;
+            }
             if (samplerate != 44100)
-                av_log_ask_for_sample(s, "Unsupported sample rate: %d\n",
-                                      samplerate);
+                avpriv_request_sample(s, "Sample rate %d", samplerate);
 
             framesize = (codec_params & 0x3FF) * 8;
             jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */
             st->codec->channels    = 2;
+            st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
             st->codec->sample_rate = samplerate;
             st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;
 
@@ -331,9 +338,14 @@ static int oma_read_header(AVFormatContext *s)
         case OMA_CODECID_ATRAC3P:
             st->codec->channels = (codec_params >> 10) & 7;
             framesize = ((codec_params & 0x3FF) * 8) + 8;
-            st->codec->sample_rate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100;
-            st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;
-            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+            samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
+            if (!samplerate) {
+                av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
+                return AVERROR_INVALIDDATA;
+            }
+            st->codec->sample_rate = samplerate;
+            st->codec->bit_rate    = samplerate * framesize * 8 / 1024;
+            avpriv_set_pts_info(st, 64, 1, samplerate);
             av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
             break;
         case OMA_CODECID_MP3:
@@ -343,6 +355,7 @@ static int oma_read_header(AVFormatContext *s)
         case OMA_CODECID_LPCM:
             /* PCM 44.1 kHz 16 bit stereo big-endian */
             st->codec->channels = 2;
+            st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
             st->codec->sample_rate = 44100;
             framesize = 1024;
             /* bit rate = sample rate x PCM block align (= 4) x 8 */