PR #25504 opened by Marti2203 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25504 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25504.patch
`decode_zlib()` accepts a zlib stream that ends (`Z_STREAM_END`) before `uncompressed_size` bytes have been produced. `s->delta` is reused between packets (`av_fast_padded_malloc()` only allocates when it has to grow), so the part that was not written still holds the previous packet's data, and `decode_move()`, `decode_dlta()` and the cursor code use it as if it had just been decoded. For example, a RASC AVI whose second `MOUS` chunk declares 24 bytes of cursor data but whose zlib stream inflates to 3 bytes is decoded without any error, and 21 bytes of the first packet's cursor end up in the second frame; a `DLTA` chunk that inflates to 2 of 758 declared bytes runs the delta opcodes over the previous packet's data. The patch returns `AVERROR_INVALIDDATA` when fewer than `uncompressed_size` bytes were inflated; all three callers then read exactly `uncompressed_size` bytes from `s->delta`. With it, both cases above report "Inflated 3 of 24 bytes" / "Inflated 2 of 758 bytes" and the packet is dropped, while the same files with complete streams decode to identical framemd5 output as before. A file whose very first packet is short (where the tail was zeroed by the first allocation) is now rejected too. I could not find real RASC samples (none in fate-suite, samples.ffmpeg.org or trac), so this was tested with constructed files only; if short streams turn up in real files, zero-filling the rest would be the alternative. This issue was found by an LLM-Enhanced Static Analysis Engine and verified manually. 🤖 Generated with [Claude Code](https://claude.com/claude-code) From 9def621750195a11eb1e120f934394f1e110329c Mon Sep 17 00:00:00 2001 From: Martin Mirchev <[email protected]> Date: Tue, 27 Oct 2026 09:59:22 +0800 Subject: [PATCH] avcodec/rasc: fail if the zlib data is shorter than the declared size decode_zlib() accepted a stream that ended before uncompressed_size bytes were produced. s->delta is reused between packets, so the rest of it still held the previous packet's data, which decode_move(), decode_dlta() and the cursor code then used as if it had just been decoded. Return AVERROR_INVALIDDATA instead. Signed-off-by: Martin Mirchev <[email protected]> --- libavcodec/rasc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/rasc.c b/libavcodec/rasc.c index d784a440633..654c9145f9f 100644 --- a/libavcodec/rasc.c +++ b/libavcodec/rasc.c @@ -204,6 +204,12 @@ static int decode_zlib(AVCodecContext *avctx, const AVPacket *avpkt, return AVERROR_INVALIDDATA; } + if (zstream->total_out < uncompressed_size) { + av_log(avctx, AV_LOG_ERROR, "Inflated %lu of %u bytes.\n", + zstream->total_out, uncompressed_size); + return AVERROR_INVALIDDATA; + } + return 0; } -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
