PR #25849 opened by romainhedouin URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25849 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25849.patch
An object with more than 65528 bytes of pixel data got truncated 16 bit lengths, but the encoder still returned success. Return AVERROR(EINVAL) instead. ffmpeg then stops with "Subtitle encoding failed". Although probably rare in the real world, it can technically happen for example with subtitles of 1150x220 pixels (3 lines of captions at 1080p with an outline) encoded with 8 bits per pixel as PGS input is, which needs about 66 KB ; or two lines on a 4K canvas (about 2300x270 pixels), which needs over 100 KB. Testing: independent spec parser for the exact limit, differential against master, ASan/UBSan, leaks, DVB FATE tests. Found during a code review sweep of ffmpeg using an LLM. <!-- If this PR requires new FATE test samples, attach them to the PR and list their target paths below (relative to the fate-suite root). Attached filenames must match the sample's filename: ```fate-samples # e.g. vorbis/new-sample.ogg ``` --> >From 1e7cdd5fe8eee114fa5b70f14530f057fbe1ac08 Mon Sep 17 00:00:00 2001 From: romainhedouin <[email protected]> Date: Sat, 7 Nov 2026 19:13:59 +0100 Subject: [PATCH] avcodec/dvbsubenc: reject object data that does not fit in one segment segment_length and the top and bottom field lengths of an object data segment are 16 bit fields. When the pixel data of an object needed more than 65528 bytes they were written truncated, but the encoder still returned success, and the decoder then skipped the object or showed it cut. A three line caption of about 1150x220 pixels coded with 8 bits per pixel, which is what the encoder uses for PGS input, needs about 66 KB. Return AVERROR(EINVAL) instead, like the other limits here. ffmpeg then stops with "Subtitle encoding failed". Found during a code review sweep of ffmpeg using an LLM. Signed-off-by: romainhedouin <[email protected]> --- libavcodec/dvbsubenc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c index a7507723568..698e291ddac 100644 --- a/libavcodec/dvbsubenc.c +++ b/libavcodec/dvbsubenc.c @@ -544,6 +544,13 @@ static int dvbsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int buf_size, bytestream_put_be16(&pbottom_field_len, q - bottom_ptr); } + /* segment_length is 16 bits, and so are the two field lengths */ + if (q - pseg_len - 2 > 0xFFFF) { + av_log(avctx, AV_LOG_ERROR, + "Object %d needs a segment of %td bytes, the maximum is 65535\n", + object_id, q - pseg_len - 2); + return AVERROR(EINVAL); + } bytestream_put_be16(&pseg_len, q - pseg_len - 2); } } -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
