avcodec/ffv1dec: Allocate the minimum size for fltmap and fltmap32 with the current implementation

Found-by: Lynne
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer
2026-03-19 19:34:37 +01:00
committed by michaelni
parent 3d4461e16d
commit 313e776ba7
2 changed files with 27 additions and 16 deletions

View File

@@ -110,6 +110,8 @@ static int decode_plane(FFV1Context *f, FFV1SliceContext *sc,
if (sc->remap) {
bits = av_ceil_log2(sc->remap_count[remap_index]);
mask = (1<<bits)-1;
av_assert0(sc->fltmap_size[remap_index] >= (mask + 1) * sizeof(*sc->fltmap[remap_index]));
} else {
bits = f->avctx->bits_per_raw_sample;
}
@@ -299,9 +301,8 @@ static int decode_remap(FFV1Context *f, FFV1SliceContext *sc)
{
unsigned int end = (1LL<<f->avctx->bits_per_raw_sample) - 1;
int flip = sc->remap == 2 ? (end>>1) : 0;
const int pixel_num = sc->slice_width * sc->slice_height;
for (int p= 0; p < 1 + 2*f->chroma_planes + f->transparency; p++) {
for (int p = 0; p < 1 + 2*f->chroma_planes + f->transparency; p++) {
int j = 0;
int lu = 0;
uint8_t state[2][3][32];
@@ -309,6 +310,22 @@ static int decode_remap(FFV1Context *f, FFV1SliceContext *sc)
int mul[4096+1];
int mul_count;
const int is_chroma = (p == 1 || p == 2) && f->chroma_planes;
const int plane_width = AV_CEIL_RSHIFT(sc->slice_width , is_chroma ? f->chroma_h_shift : 0);
const int plane_height = AV_CEIL_RSHIFT(sc->slice_height, is_chroma ? f->chroma_v_shift : 0);
const int pixel_num = FFMIN(plane_width * plane_height, end + 1LL);
const size_t fltmap_ceil = 1ULL << av_ceil_log2(pixel_num);
if (f->avctx->bits_per_raw_sample == 32) {
av_fast_malloc(&sc->fltmap32[p], &sc->fltmap32_size[p], fltmap_ceil * sizeof(*sc->fltmap32[p]));
if (!sc->fltmap32[p])
return AVERROR(ENOMEM);
} else {
av_fast_malloc(&sc->fltmap[p] , &sc->fltmap_size[p] , fltmap_ceil * sizeof(*sc->fltmap[p]));
if (!sc->fltmap[p])
return AVERROR(ENOMEM);
}
memset(state, 128, sizeof(state));
mul_count = ff_ffv1_get_symbol(&sc->c, state[0][0], 0);
@@ -400,20 +417,6 @@ static int decode_slice(AVCodecContext *c, void *arg)
y = sc->slice_y;
if (sc->remap) {
const int pixel_num = sc->slice_width * sc->slice_height;
for(int p = 0; p < 1 + 2*f->chroma_planes + f->transparency ; p++) {
if (f->avctx->bits_per_raw_sample == 32) {
av_fast_malloc(&sc->fltmap32[p], &sc->fltmap32_size[p], pixel_num * sizeof(*sc->fltmap32[p]));
if (!sc->fltmap32[p])
return AVERROR(ENOMEM);
} else {
av_fast_malloc(&sc->fltmap[p], &sc->fltmap_size[p], pixel_num * sizeof(*sc->fltmap[p]));
if (!sc->fltmap[p])
return AVERROR(ENOMEM);
}
}
ret = decode_remap(f, sc);
if (ret < 0)
return ret;

View File

@@ -151,6 +151,14 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
ff_ffv1_compute_bits_per_plane(f, sc, bits, &offset, mask, f->avctx->bits_per_raw_sample);
if (sc->remap)
for (int p=0; p<3+f->transparency; p++) {
if (f->avctx->bits_per_raw_sample == 32) {
av_assert0(sc->fltmap32_size[p] >= (mask[p] + 1LL) * sizeof(*sc->fltmap32[p]));
} else
av_assert0(sc->fltmap_size[p] >= (mask[p] + 1LL) * sizeof(*sc->fltmap[p]));
}
if (sc->slice_coding_mode == 1)
ac = 1;