Commit 6dde65d7 authored by Michael Niedermayer's avatar Michael Niedermayer

avcodec/ac3dec: Optimize frame start search

Fixes: Timeout
Fixes: 11619/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AC3_FIXED_fuzzer-5632398021099520
Fixes: 11620/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AC3_fuzzer-5711996515778560
Fixes: 11658/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_EAC3_fuzzer-5701006524940288

Before: Executed clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AC3_FIXED_fuzzer-5632398021099520 in 20338 ms
After:  Executed clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AC3_FIXED_fuzzer-5632398021099520 in 11825 ms

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpegSigned-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 19dc5cda
...@@ -1467,6 +1467,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, ...@@ -1467,6 +1467,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
int buf_size, full_buf_size = avpkt->size; int buf_size, full_buf_size = avpkt->size;
AC3DecodeContext *s = avctx->priv_data; AC3DecodeContext *s = avctx->priv_data;
int blk, ch, err, offset, ret; int blk, ch, err, offset, ret;
int i;
int skip = 0, got_independent_frame = 0; int skip = 0, got_independent_frame = 0;
const uint8_t *channel_map; const uint8_t *channel_map;
uint8_t extended_channel_map[EAC3_MAX_CHANNELS]; uint8_t extended_channel_map[EAC3_MAX_CHANNELS];
...@@ -1477,14 +1478,21 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, ...@@ -1477,14 +1478,21 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
s->superframe_size = 0; s->superframe_size = 0;
buf_size = full_buf_size; buf_size = full_buf_size;
while (buf_size > 2) { for (i = 1; i < buf_size; i += 2) {
if (AV_RB16(buf) != 0x770B && AV_RL16(buf) != 0x770B) { if (buf[i] == 0x77 || buf[i] == 0x0B) {
buf += 1; if ((buf[i] ^ buf[i-1]) == (0x77 ^ 0x0B)) {
buf_size -= 1; i--;
continue; break;
} else if ((buf[i] ^ buf[i+1]) == (0x77 ^ 0x0B)) {
break;
}
} }
break;
} }
if (i >= buf_size)
return AVERROR_INVALIDDATA;
buf += i;
buf_size -= i;
/* copy input buffer to decoder context to avoid reading past the end /* copy input buffer to decoder context to avoid reading past the end
of the buffer, which can be caused by a damaged input stream. */ of the buffer, which can be caused by a damaged input stream. */
if (buf_size >= 2 && AV_RB16(buf) == 0x770B) { if (buf_size >= 2 && AV_RB16(buf) == 0x770B) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment