[FFmpeg-cvslog] avcodec/bonk: decode multiple passes in intlist_read() at once
Michael Niedermayer
git at videolan.org
Mon May 1 02:04:48 EEST 2023
ffmpeg | branch: master | Michael Niedermayer <michael at niedermayer.cc> | Sat Nov 5 19:33:33 2022 +0100| [957106a24d2960e1d0359a1774b547c1292b4704] | committer: Michael Niedermayer
avcodec/bonk: decode multiple passes in intlist_read() at once
This makes the worst case much faster
Fixes: Timeout
Fixes: 51363/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BONK_fuzzer-5660734784143360
Fixes: 57957/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_BONK_fuzzer-5874095467397120
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=957106a24d2960e1d0359a1774b547c1292b4704
---
libavcodec/bonk.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/libavcodec/bonk.c b/libavcodec/bonk.c
index 5f510e4910..4a00270392 100644
--- a/libavcodec/bonk.c
+++ b/libavcodec/bonk.c
@@ -155,6 +155,7 @@ static int intlist_read(BonkContext *s, int *buf, int entries, int base_2_part)
int n_zeros = 0, step = 256, dominant = 0;
int pos = 0, level = 0;
BitCount *bits = s->bits;
+ int passes = 1;
memset(buf, 0, entries * sizeof(*buf));
if (base_2_part) {
@@ -216,24 +217,28 @@ static int intlist_read(BonkContext *s, int *buf, int entries, int base_2_part)
x = 0;
n_zeros = 0;
for (i = 0; n_zeros < entries; i++) {
+ if (x >= max_x)
+ return AVERROR_INVALIDDATA;
+
if (pos >= entries) {
pos = 0;
- level += 1 << low_bits;
+ level += passes << low_bits;
+ passes = 1;
+ if (bits[x].bit && bits[x].count > entries - n_zeros)
+ passes = bits[x].count / (entries - n_zeros);
}
if (level > 1 << 16)
return AVERROR_INVALIDDATA;
- if (x >= max_x)
- return AVERROR_INVALIDDATA;
-
if (buf[pos] >= level) {
if (bits[x].bit)
- buf[pos] += 1 << low_bits;
+ buf[pos] += passes << low_bits;
else
n_zeros++;
- bits[x].count--;
+ av_assert1(bits[x].count >= passes);
+ bits[x].count -= passes;
x += bits[x].count == 0;
}
More information about the ffmpeg-cvslog
mailing list