Commit 94e1680dbf for ffmpeg
commit 94e1680dbfe204c915ecf0c472c1fd2f052ad8a9
Author: Michael Niedermayer <michael@niedermayer.cc>
Date: Mon Oct 12 02:32:19 2026 +0200
avfilter/vf_drawbox: check the expression results before converting them to int
Fixes: out of range float to int conversion
Fixes: signed integer overflow
Fixes: 4jtp2TTOoEsQ
Found during triage of the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24765
Out of range float to int conversion Replicated through UnModified FFmpeg with UBSAN
Signed integer overflow Replicated through UnModified FFmpeg with UBSAN
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index deb117376b..3dc6437e5d 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -313,37 +313,49 @@ static int config_input(AVFilterLink *inlink)
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
goto fail;
- s->x = var_values[VAR_X] = res;
+ var_values[VAR_X] = res;
var_values[VAR_MAX] = inlink->h;
if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
goto fail;
- s->y = var_values[VAR_Y] = res;
+ var_values[VAR_Y] = res;
- var_values[VAR_MAX] = inlink->w - s->x;
+ var_values[VAR_MAX] = inlink->w - trunc(var_values[VAR_X]);
if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
goto fail;
- s->w = var_values[VAR_W] = res;
+ var_values[VAR_W] = res;
- var_values[VAR_MAX] = inlink->h - s->y;
+ var_values[VAR_MAX] = inlink->h - trunc(var_values[VAR_Y]);
if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
goto fail;
- s->h = var_values[VAR_H] = res;
+ var_values[VAR_H] = res;
var_values[VAR_MAX] = INT_MAX;
if ((ret = av_expr_parse_and_eval(&res, (expr = s->t_expr),
var_names, var_values,
NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS)
goto fail;
- s->thickness = var_values[VAR_T] = res;
+ var_values[VAR_T] = res;
}
+ if (!(fabs(var_values[VAR_X]) <= INT_MAX / 4 && fabs(var_values[VAR_Y]) <= INT_MAX / 4 &&
+ fabs(var_values[VAR_W]) <= INT_MAX / 4 && fabs(var_values[VAR_H]) <= INT_MAX / 4 &&
+ fabs(var_values[VAR_T]) <= INT_MAX)) {
+ av_log(ctx, AV_LOG_ERROR, "Position, size or thickness out of range.\n");
+ return AVERROR(EINVAL);
+ }
+ s->x = var_values[VAR_X];
+ s->y = var_values[VAR_Y];
+ s->w = var_values[VAR_W];
+ s->h = var_values[VAR_H];
+ s->thickness = var_values[VAR_T];
+
/* if w or h are zero, use the input w/h */
s->w = (s->w > 0) ? s->w : inlink->w;
s->h = (s->h > 0) ? s->h : inlink->h;