PR #23031 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23031 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23031.patch
This fixes overreads with libdav1d, because it provides non-padded data in violation to the requirements of the GetBits API. Furthermore, using the GetBits API here is wasteful, as the offsets here are known and the actual data to be copied is even byte-aligned, allowing to use memcpy. This is an alternative to #22887. >From f2e5eff3ff2141479da980fc9474a8f8ecf768a8 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Wed, 6 May 2026 15:23:01 +0200 Subject: [PATCH] avcodec/atsc_a53: Avoid GetBits API to parse A53 CC data This fixes overreads with libdav1d, because it provides non-padded data in violation to the requirements of the GetBits API. Furthermore, using the GetBits API here is wasteful, as the offsets here are known and the actual data to be copied is even byte-aligned, allowing to use memcpy. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/atsc_a53.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/libavcodec/atsc_a53.c b/libavcodec/atsc_a53.c index 1e9ea15ae0..7c88263a14 100644 --- a/libavcodec/atsc_a53.c +++ b/libavcodec/atsc_a53.c @@ -19,9 +19,9 @@ #include <stddef.h> #include <stdint.h> +#include "libavutil/intreadwrite.h" #include "libavutil/mem.h" #include "atsc_a53.h" -#include "get_bits.h" int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size) @@ -69,33 +69,25 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, int ff_parse_a53_cc(AVBufferRef **pbuf, const uint8_t *data, int size) { AVBufferRef *buf = *pbuf; - GetBitContext gb; size_t new_size, old_size = buf ? buf->size : 0; int ret, cc_count; if (size < 3) return AVERROR_INVALIDDATA; - ret = init_get_bits8(&gb, data, size); - if (ret < 0) - return ret; - - if (get_bits(&gb, 8) != 0x3) // user_data_type_code + if (data[0] != 0x3) // user_data_type_code return 0; - skip_bits(&gb, 1); // reserved - if (!get_bits(&gb, 1)) // process_cc_data_flag + if (!(data[1] & 0x40)) // process_cc_data_flag return 0; - skip_bits(&gb, 1); // zero bit - cc_count = get_bits(&gb, 5); + cc_count = data[1] & 0x1F; if (!cc_count) return 0; - skip_bits(&gb, 8); // reserved - + // content of data[2] is reserved /* 3 bytes per CC plus one byte marker_bits at the end */ - if (cc_count * 3 >= (get_bits_left(&gb) >> 3)) + if (cc_count * 3 >= size - 3) return AVERROR_INVALIDDATA; new_size = (old_size + cc_count * 3); @@ -110,11 +102,7 @@ int ff_parse_a53_cc(AVBufferRef **pbuf, const uint8_t *data, int size) buf = *pbuf; /* Use of av_buffer_realloc assumes buffer is writeable */ - for (int i = 0; i < cc_count; i++) { - buf->data[old_size++] = get_bits(&gb, 8); - buf->data[old_size++] = get_bits(&gb, 8); - buf->data[old_size++] = get_bits(&gb, 8); - } + memcpy(buf->data + old_size, data + 3, cc_count * 3); return cc_count; } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
