]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/oma.c
thpdemux: Check that packed sizes are within the files data size and filesize.
[ffmpeg] / libavformat / oma.c
index 09fa2ca985c8be6031e373958ab1c438e37445a6..0363f7fc50697e1411ba18a8e1ab30e0b0201236 100644 (file)
@@ -41,6 +41,7 @@
  */
 
 #include "avformat.h"
+#include "internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/des.h"
 #include "pcm.h"
@@ -60,9 +61,10 @@ enum {
 };
 
 static const AVCodecTag codec_oma_tags[] = {
-    { CODEC_ID_ATRAC3,  OMA_CODECID_ATRAC3 },
-    { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P },
-    { CODEC_ID_MP3,     OMA_CODECID_MP3 },
+    { CODEC_ID_ATRAC3,      OMA_CODECID_ATRAC3 },
+    { CODEC_ID_ATRAC3P,     OMA_CODECID_ATRAC3P },
+    { CODEC_ID_MP3,         OMA_CODECID_MP3 },
+    { CODEC_ID_PCM_S16BE,   OMA_CODECID_LPCM },
 };
 
 static const uint64_t leaf_table[] = {
@@ -155,7 +157,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;
@@ -174,6 +176,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);
@@ -201,8 +206,8 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
     while (em) {
         if (!strcmp(em->tag, "GEOB") &&
             (geob = em->data) &&
-            !strcmp(geob->description, "OMG_LSI") ||
-            !strcmp(geob->description, "OMG_BKLSI")) {
+            (!strcmp(geob->description, "OMG_LSI") ||
+             !strcmp(geob->description, "OMG_BKLSI"))) {
             break;
         }
         em = em->next;
@@ -244,14 +249,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 < sizeof(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)) {
@@ -307,7 +312,7 @@ static int oma_read_header(AVFormatContext *s,
 
     codec_params = AV_RB24(&buf[33]);
 
-    st = av_new_stream(s, 0);
+    st = avformat_new_stream(s, NULL);
     if (!st)
         return AVERROR(ENOMEM);
 
@@ -343,20 +348,30 @@ static int oma_read_header(AVFormatContext *s,
             AV_WL16(&edata[10], 1);             // always 1
             // AV_WL16(&edata[12], 0);          // always 0
 
-            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
             break;
         case OMA_CODECID_ATRAC3P:
             st->codec->channels = (codec_params >> 10) & 7;
             framesize = ((codec_params & 0x3FF) * 8) + 8;
             st->codec->sample_rate = srate_tab[(codec_params >> 13) & 7]*100;
             st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;
-            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
             av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
             break;
         case OMA_CODECID_MP3:
             st->need_parsing = AVSTREAM_PARSE_FULL;
             framesize = 1024;
             break;
+        case OMA_CODECID_LPCM:
+            /* PCM 44.1 kHz 16 bit stereo big-endian */
+            st->codec->channels = 2;
+            st->codec->sample_rate = 44100;
+            framesize = 1024;
+            /* bit rate = sample rate x PCM block align (= 4) x 8 */
+            st->codec->bit_rate = st->codec->sample_rate * 32;
+            st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
+            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+            break;
         default:
             av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]);
             return -1;
@@ -393,14 +408,20 @@ static int oma_read_probe(AVProbeData *p)
     unsigned tag_len = 0;
 
     buf = p->buf;
-    /* version must be 3 and flags byte zero */
-    if (ff_id3v2_match(buf, ID3v2_EA3_MAGIC) && buf[3] == 3 && !buf[4])
-        tag_len = ff_id3v2_tag_len(buf);
 
-    // This check cannot overflow as tag_len has at most 28 bits
-    if (p->buf_size < tag_len + 5)
+    if (p->buf_size < ID3v2_HEADER_SIZE ||
+        !ff_id3v2_match(buf, ID3v2_EA3_MAGIC) ||
+        buf[3] != 3 || // version must be 3
+        buf[4]) // flags byte zero
         return 0;
 
+    tag_len = ff_id3v2_tag_len(buf);
+
+    /* This check cannot overflow as tag_len has at most 28 bits */
+    if (p->buf_size < tag_len + 5)
+        /* EA3 header comes late, might be outside of the probe buffer */
+        return AVPROBE_SCORE_MAX / 2;
+
     buf += tag_len;
 
     if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)