summaryrefslogtreecommitdiff
path: root/libavcodec/bonk.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2022-11-05 19:33:33 +0100
committerMichael Niedermayer <michael@niedermayer.cc>2023-05-01 00:48:32 +0200
commit957106a24d2960e1d0359a1774b547c1292b4704 (patch)
tree0047c34f5ef0e1428492328e9471d5e733cd32b2 /libavcodec/bonk.c
parente734e165442b4bf1598b167c373928d993371f0d (diff)
downloadffmpeg-957106a24d2960e1d0359a1774b547c1292b4704.tar.gz
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@niedermayer.cc>
Diffstat (limited to 'libavcodec/bonk.c')
-rw-r--r--libavcodec/bonk.c17
1 files 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;
}