mpegaudiodecheader: check the header in avpriv_mpegaudio_decode_header
authorAnton Khirnov <anton@khirnov.net>
Fri, 9 Oct 2015 13:16:46 +0000 (15:16 +0200)
committerAnton Khirnov <anton@khirnov.net>
Sat, 12 Dec 2015 20:25:42 +0000 (21:25 +0100)
Almost all the places from which this function is called already check
the header manually and in the two that don't (the mp3 muxer) the check
should not cause any problems.

libavcodec/libmp3lame.c
libavcodec/mpegaudiodec_template.c
libavcodec/mpegaudiodecheader.c
libavformat/mp3dec.c
libavformat/mp3enc.c

index 966212dcae8146cbaf44303ba1df6f063122536b..e4d0e001032dd2a7b8ea3d854e57beceb77feab6 100644 (file)
@@ -239,11 +239,12 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     if (s->buffer_index < 4)
         return 0;
     h = AV_RB32(s->buffer);
-    if (ff_mpa_check_header(h) < 0) {
+
+    ret = avpriv_mpegaudio_decode_header(&hdr, h);
+    if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Invalid mp3 header at start of buffer\n");
         return AVERROR_BUG;
-    }
-    if (avpriv_mpegaudio_decode_header(&hdr, h)) {
+    } else if (ret) {
         av_log(avctx, AV_LOG_ERROR, "free format output not supported\n");
         return -1;
     }
index ba1f82b99f55421ba7bd2f346d9bc26bde559e2f..184d67bf3bd8e07eaaabf69a0e29de8e3ecc473f 100644 (file)
@@ -1631,12 +1631,12 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr,
         return AVERROR_INVALIDDATA;
 
     header = AV_RB32(buf);
-    if (ff_mpa_check_header(header) < 0) {
+
+    ret = avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
+    if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Header missing\n");
         return AVERROR_INVALIDDATA;
-    }
-
-    if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
+    } else if (ret == 1) {
         /* free format: prepare to compute frame size */
         s->frame_size = -1;
         return AVERROR_INVALIDDATA;
@@ -1706,12 +1706,11 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data,
     // Get header and restore sync word
     header = AV_RB32(buf) | 0xffe00000;
 
-    if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame
+    ret = avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
+    if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n");
-        return AVERROR_INVALIDDATA;
+        return ret;
     }
-
-    avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
     /* update codec info */
     avctx->sample_rate = s->sample_rate;
     avctx->channels    = s->nb_channels;
@@ -1903,11 +1902,10 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
         }
         header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
 
-        if (ff_mpa_check_header(header) < 0) // Bad header, discard block
+        ret = avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
+        if (ret < 0) // Bad header, discard block
             break;
 
-        avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
-
         if (ch + m->nb_channels > avctx->channels ||
             s->coff[fr] + m->nb_channels > avctx->channels) {
             av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
index 3d840d7ecbd024198b132c6f758e1e2bd2d4e3d3..175f8c2ca787af6ed6390c8e79f293d9e9a9968f 100644 (file)
@@ -36,6 +36,12 @@ int avpriv_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header)
 {
     int sample_rate, frame_size, mpeg25, padding;
     int sample_rate_index, bitrate_index;
+    int ret;
+
+    ret = ff_mpa_check_header(header);
+    if (ret < 0)
+        return ret;
+
     if (header & (1<<20)) {
         s->lsf = (header & (1<<19)) ? 0 : 1;
         mpeg25 = 0;
@@ -116,9 +122,6 @@ int avpriv_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_r
 {
     MPADecodeHeader s1, *s = &s1;
 
-    if (ff_mpa_check_header(head) != 0)
-        return -1;
-
     if (avpriv_mpegaudio_decode_header(s, head) != 0) {
         return -1;
     }
index a875b82c0a23d3843d5f2cf872115974e50ff412..8904797491b268738cbc2bd63707963a6a26cd30 100644 (file)
@@ -275,14 +275,16 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
     MPADecodeHeader c;
     int vbrtag_size = 0;
     MP3DecContext *mp3 = s->priv_data;
+    int ret;
 
     ffio_init_checksum(s->pb, ff_crcA001_update, 0);
 
     v = avio_rb32(s->pb);
-    if(ff_mpa_check_header(v) < 0)
-      return -1;
 
-    if (avpriv_mpegaudio_decode_header(&c, v) == 0)
+    ret = avpriv_mpegaudio_decode_header(&c, v);
+    if (ret < 0)
+        return ret;
+    else if (ret == 0)
         vbrtag_size = c.frame_size;
     if(c.layer != 3)
         return -1;
@@ -388,8 +390,8 @@ static int check(AVIOContext *pb, int64_t pos, int64_t *out_pos)
 
         header = avio_rb32(pb);
 
-        if (ff_mpa_check_header(header) < 0 ||
-            avpriv_mpegaudio_decode_header(&mh, header))
+
+        if (avpriv_mpegaudio_decode_header(&mh, header))
             break;
         out_pos[i] = off;
     }
index e4c6dbb2233c72cae65cce06f195eaf2454b354a..42b329651266cbe0037aedf3fbb0b9345f20bc7f 100644 (file)
@@ -306,11 +306,12 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
 
     if (mp3->xing_offset && pkt->size >= 4) {
         MPADecodeHeader c;
+        int ret;
         uint32_t h;
 
         h = AV_RB32(pkt->data);
-        if (ff_mpa_check_header(h) == 0) {
-            avpriv_mpegaudio_decode_header(&c, h);
+        ret = avpriv_mpegaudio_decode_header(&c, h);
+        if (ret >= 0) {
             if (!mp3->initial_bitrate)
                 mp3->initial_bitrate = c.bit_rate;
             if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))