diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2019-10-02 21:48:40 +0300 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2019-10-10 15:34:20 +0300 |
commit | f6df99dba1ae64b05d08fba8160d13eb9795042f (patch) | |
tree | 06158b77fa68f55a7bc63cb03082205e23697997 /libavcodec/dstdec.c | |
parent | a5d29812ec364ad4b83b5c2dba281f1b559a518b (diff) |
avcodec/dstdec: Check for input exhaustion
Fixes: Timeout (239sec -> 16sec)
Fixes: 17811/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_DST_fuzzer-5715508149616640
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: Paul B Mahol <onemda@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec/dstdec.c')
-rw-r--r-- | libavcodec/dstdec.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c index 8a1bc6a738..48271b10f7 100644 --- a/libavcodec/dstdec.c +++ b/libavcodec/dstdec.c @@ -56,6 +56,7 @@ static const int8_t probs_code_pred_coeff[3][3] = { typedef struct ArithCoder { unsigned int a; unsigned int c; + int overread; } ArithCoder; typedef struct Table { @@ -172,6 +173,7 @@ static void ac_init(ArithCoder *ac, GetBitContext *gb) { ac->a = 4095; ac->c = get_bits(gb, 12); + ac->overread = 0; } static av_always_inline void ac_get(ArithCoder *ac, GetBitContext *gb, int p, int *e) @@ -191,6 +193,8 @@ static av_always_inline void ac_get(ArithCoder *ac, GetBitContext *gb, int p, in if (ac->a < 2048) { int n = 11 - av_log2(ac->a); ac->a <<= n; + if (get_bits_left(gb) < n) + ac->overread ++; ac->c = (ac->c << n) | get_bits(gb, n); } } @@ -339,6 +343,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, prob = 128; } + if (ac->overread > 16) + return AVERROR_INVALIDDATA; + ac_get(ac, gb, prob, &residual); v = ((predict >> 15) ^ residual) & 1; dsd[((i >> 3) * channels + ch) << 2] |= v << (7 - (i & 0x7 )); |