[FFmpeg-devel] [PATCH] avformat/ac3dec: always skip junk bytes before sync bytes

Paul B Mahol onemda at gmail.com
Sun Nov 25 13:18:15 EET 2018


Fixes #7278.

Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 libavcodec/ac3dec.c  | 19 ++++++++++++++++---
 libavformat/ac3dec.c |  2 +-
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 43b22b7654..90e4dc8a1f 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -1467,7 +1467,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
     int buf_size, full_buf_size = avpkt->size;
     AC3DecodeContext *s = avctx->priv_data;
     int blk, ch, err, offset, ret;
-    int got_independent_frame = 0;
+    int skip = 0, got_independent_frame = 0;
     const uint8_t *channel_map;
     uint8_t extended_channel_map[EAC3_MAX_CHANNELS];
     const SHORTFLOAT *output[AC3_MAX_CHANNELS];
@@ -1477,6 +1477,14 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
     s->superframe_size = 0;
 
     buf_size = full_buf_size;
+    while (buf_size > 2) {
+        if (AV_RB16(buf) != 0x770B && AV_RL16(buf) != 0x770B) {
+            buf += 1;
+            buf_size -= 1;
+            continue;
+        }
+        break;
+    }
     /* copy input buffer to decoder context to avoid reading past the end
        of the buffer, which can be caused by a damaged input stream. */
     if (buf_size >= 2 && AV_RB16(buf) == 0x770B) {
@@ -1637,6 +1645,10 @@ dependent_frame:
         AC3HeaderInfo hdr;
         int err;
 
+        if (buf_size - s->frame_size <= 16)
+            skip = buf_size - s->frame_size;
+            goto skip;
+
         if ((ret = init_get_bits8(&s->gbc, buf + s->frame_size, buf_size - s->frame_size)) < 0)
             return ret;
 
@@ -1657,6 +1669,7 @@ dependent_frame:
             }
         }
     }
+skip:
 
     frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;
 
@@ -1796,9 +1809,9 @@ dependent_frame:
     *got_frame_ptr = 1;
 
     if (!s->superframe_size)
-        return FFMIN(full_buf_size, s->frame_size);
+        return FFMIN(full_buf_size, s->frame_size + skip);
 
-    return FFMIN(full_buf_size, s->superframe_size);
+    return FFMIN(full_buf_size, s->superframe_size + skip);
 }
 
 /**
diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c
index 6f423ff7eb..2718061bdc 100644
--- a/libavformat/ac3dec.c
+++ b/libavformat/ac3dec.c
@@ -47,7 +47,7 @@ static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id)
             uint16_t frame_size;
             int i, ret;
 
-            if(!memcmp(buf2, "\x1\x10\0\0\0\0\0\0", 8)) {
+            if(!memcmp(buf2, "\x1\x10", 2)) {
                 if (buf2 + 16 > end)
                     break;
                 buf2+=16;
-- 
2.17.1



More information about the ffmpeg-devel mailing list