avfilter/vf_stack: add checks for the final canvas dimensions

Prevents potential integer overflows when trying to stitch absurdly huge images together.

Fixes #YWH-PGM40646-38.

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer
2026-01-03 21:31:30 -03:00
parent 649a4e98f4
commit 4fad136704

View File

@@ -234,6 +234,8 @@ static int config_output(AVFilterLink *outlink)
item->y[1] = item->y[2] = AV_CEIL_RSHIFT(height, s->desc->log2_chroma_h);
item->y[0] = item->y[3] = height;
if (height > INT_MAX - ctx->inputs[i]->h)
return AVERROR(EINVAL);
height += ctx->inputs[i]->h;
}
}
@@ -259,6 +261,8 @@ static int config_output(AVFilterLink *outlink)
return ret;
}
if (width > INT_MAX - ctx->inputs[i]->w)
return AVERROR(EINVAL);
width += ctx->inputs[i]->w;
}
}
@@ -294,8 +298,13 @@ static int config_output(AVFilterLink *outlink)
item->y[1] = item->y[2] = AV_CEIL_RSHIFT(inh, s->desc->log2_chroma_h);
item->y[0] = item->y[3] = inh;
if (inw > INT_MAX - ctx->inputs[k]->w)
return AVERROR(EINVAL);
inw += ctx->inputs[k]->w;
}
if (height > INT_MAX - row_height)
return AVERROR(EINVAL);
height += row_height;
if (!i)
width = inw;
@@ -351,26 +360,41 @@ static int config_output(AVFilterLink *outlink)
if (size == i || size < 0 || size >= s->nb_inputs)
return AVERROR(EINVAL);
if (!j)
if (!j) {
if (inw > INT_MAX - ctx->inputs[size]->w)
return AVERROR(EINVAL);
inw += ctx->inputs[size]->w;
else
} else {
if (inh > INT_MAX - ctx->inputs[size]->w)
return AVERROR(EINVAL);
inh += ctx->inputs[size]->w;
}
} else if (sscanf(arg3, "h%d", &size) == 1) {
if (size == i || size < 0 || size >= s->nb_inputs)
return AVERROR(EINVAL);
if (!j)
if (!j) {
if (inw > INT_MAX - ctx->inputs[size]->h)
return AVERROR(EINVAL);
inw += ctx->inputs[size]->h;
else
} else {
if (inh > INT_MAX - ctx->inputs[size]->h)
return AVERROR(EINVAL);
inh += ctx->inputs[size]->h;
}
} else if (sscanf(arg3, "%d", &size) == 1) {
if (size < 0)
return AVERROR(EINVAL);
if (!j)
if (!j) {
if (inw > INT_MAX - size)
return AVERROR(EINVAL);
inw += size;
else
} else {
if (inh > INT_MAX - size)
return AVERROR(EINVAL);
inh += size;
}
} else {
return AVERROR(EINVAL);
}
@@ -384,6 +408,8 @@ static int config_output(AVFilterLink *outlink)
item->y[1] = item->y[2] = AV_CEIL_RSHIFT(inh, s->desc->log2_chroma_h);
item->y[0] = item->y[3] = inh;
if (inlink->w > INT_MAX - inw || inlink->h > INT_MAX - inh)
return AVERROR(EINVAL);
width = FFMAX(width, inlink->w + inw);
height = FFMAX(height, inlink->h + inh);
}