PR #24620 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24620 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24620.patch
copy_bits() silently writes nothing when the requested bits do not fit the 256 byte superframe cache or exceed what is left in the packet, but sframe_cache_size was set to the requested count regardless. On the next packet the spillover bits were then appended at offset 0 and decoded as a superframe of their own, or with no spillover, stale bytes from an earlier packet were decoded again. Use put_bits_count() so the size always matches the cache content. A leftover larger than the cache is dropped instead, which is correct: a speech superframe never needs more than about 1300 bits, so such a leftover cannot be one. Bit reads never left sframe_cache, so this is not a memory safety issue; the bogus superframes and the decoder errors they produced on the affected samples are gone. Using put_bits_count() for the size was suggested by the reporter. Found-by: zhang xingxing <[email protected]> Fixes: ZAKu08c7UMiZ >From 770640b458e58f73e61c36015f308a1ec3ee5065 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 21 Sep 2026 23:36:48 +0200 Subject: [PATCH] avcodec/wmavoice: set sframe_cache_size to the number of bits actually cached copy_bits() silently writes nothing when the requested bits do not fit the 256 byte superframe cache or exceed what is left in the packet, but sframe_cache_size was set to the requested count regardless. On the next packet the spillover bits were then appended at offset 0 and decoded as a superframe of their own, or with no spillover, stale bytes from an earlier packet were decoded again. Use put_bits_count() so the size always matches the cache content. A leftover larger than the cache is dropped instead, which is correct: a speech superframe never needs more than about 1300 bits, so such a leftover cannot be one. Bit reads never left sframe_cache, so this is not a memory safety issue; the bogus superframes and the decoder errors they produced on the affected samples are gone. Using put_bits_count() for the size was suggested by the reporter. Found-by: zhang xingxing <[email protected]> Fixes: ZAKu08c7UMiZ --- libavcodec/wmavoice.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 7fc735ad1d..c3cd053ba9 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1960,8 +1960,8 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame, s->spillover_nbits = avpkt->size * 8 - cnt; } copy_bits(&s->pb, buf, size, gb, s->spillover_nbits); + s->sframe_cache_size = put_bits_count(&s->pb); flush_put_bits(&s->pb); - s->sframe_cache_size += s->spillover_nbits; if ((res = synth_superframe(ctx, frame, got_frame_ptr)) == 0 && *got_frame_ptr) { cnt += s->spillover_nbits; @@ -1993,10 +1993,11 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame, res = cnt >> 3; return res; } - } else if ((s->sframe_cache_size = pos) > 0) { + } else if (pos > 0) { /* ... cache it for spillover in next packet */ init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE); - copy_bits(&s->pb, buf, size, gb, s->sframe_cache_size); + copy_bits(&s->pb, buf, size, gb, pos); + s->sframe_cache_size = put_bits_count(&s->pb); // FIXME bad - just copy bytes as whole and add use the // skip_bits_next field } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
