avfilter/scale_eval: Avoid undefined behavior with double to int cast

We use INT32_MIN/MAX so as to ensure we dont have to deal with 64bit width or height
on a int is int64 system. int64 width would overflow in a system where we assume the product of 2
values fit in int64

Fixes: #YWH-PGM40646-14
Found-by: An0n99X
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer
2026-01-07 22:56:10 +01:00
committed by Timo Rothenpieler
parent 5bbc8f828e
commit 805931dfc8
2 changed files with 20 additions and 2 deletions

View File

@@ -83,18 +83,27 @@ int ff_scale_eval_dimensions(void *log_ctx,
av_expr_parse_and_eval(&res, (expr = w_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, log_ctx);
eval_w = var_values[VAR_OUT_W] = var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res;
var_values[VAR_OUT_W] = var_values[VAR_OW] = res == 0 ? inlink->w : trunc(res);
if ((ret = av_expr_parse_and_eval(&res, (expr = h_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0)
goto fail;
if (!(res >= INT32_MIN && res <= INT32_MAX)) {
ret = AVERROR(EINVAL);
goto fail;
}
eval_h = var_values[VAR_OUT_H] = var_values[VAR_OH] = (int) res == 0 ? inlink->h : (int) res;
/* evaluate again the width, as it may depend on the output height */
if ((ret = av_expr_parse_and_eval(&res, (expr = w_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0)
goto fail;
if (!(res >= INT32_MIN && res <= INT32_MAX)) {
ret = AVERROR(EINVAL);
goto fail;
}
eval_w = (int) res == 0 ? inlink->w : (int) res;
*ret_w = eval_w;

View File

@@ -283,17 +283,26 @@ static int config_props(AVFilterLink *outlink)
av_expr_parse_and_eval(&res, (expr = s->w_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, ctx);
s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
var_values[VAR_OUT_W] = var_values[VAR_OW] = trunc(res);
if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
goto fail;
if (!(res >= INT32_MIN && res <= INT32_MAX)) {
ret = AVERROR(EINVAL);
goto fail;
}
s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
/* evaluate again the width, as it may depend on the output height */
if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
goto fail;
if (!(res >= INT32_MIN && res <= INT32_MAX)) {
ret = AVERROR(EINVAL);
goto fail;
}
s->w = res;
w = s->w;