diff options
author | Oneric <oneric@oneric.stub> | 2023-10-08 13:48:13 +0200 |
---|---|---|
committer | Oneric <oneric@oneric.stub> | 2023-10-16 20:42:56 +0200 |
commit | 3fdaae70c98b7b169349ffb7e4831357587e63d9 (patch) | |
tree | f27a43284fc42f3b6e70d6d040ee280b37c73d3d | |
parent | 358770835248e26241e4796f38f02073a3bae252 (diff) | |
download | libass-3fdaae70c98b7b169349ffb7e4831357587e63d9.tar.bz2 libass-3fdaae70c98b7b169349ffb7e4831357587e63d9.tar.xz |
api: limit resolutions to be representable in a single ASS_Image
It appears plausible for the problem from
358770835248e26241e4796f38f02073a3bae252 to
affect more places in the rendering code.
However, for resolutions large enough to exhibit this
problem, there will likely be playback problems anyway.
Either API users will be unable to allocate a sufficiently large
buffer to blend into (> SIZE_MAX), or there will be issues during
playback with only parts of the subtitles actually being rendered
as larger events cannot create an ASS_Image (> INT_MAX).
Indeed a quick check reveals at least some truncations on floating point
to int conversion, although in this instance no OOB acceses occured.
libass/ass_render.c:3040:35: runtime error: 3.27509e+09 is outside the range of representable values of type 'int'
Given this, the new limits seem unlikely to affect any valid use cases.
Thus limit the permissable frame size appropiately and
for consistency apply the same limit to storage size.
As a bonus and to avoid division by zero, both extents
will now always be set to zero if either one is invalid.
With this the check specific to BorderStyle=4 from
358770835248e26241e4796f38f02073a3bae252
is no longer needed, since its w and h are already
effectively limited to at most frame size.
-rw-r--r-- | libass/ass_render.c | 2 | ||||
-rw-r--r-- | libass/ass_render_api.c | 8 |
2 files changed, 7 insertions, 3 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c index 138c11a..f95479c 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -2812,7 +2812,7 @@ static void add_background(RenderContext *state, EventImages *event_images) bottom = FFMINMAX(bottom, 0, render_priv->height); int w = right - left; int h = bottom - top; - if (w < 1 || h < 1 || w > FFMIN(INT_MAX, SIZE_MAX) / h) + if (w < 1 || h < 1) return; void *nbuffer = ass_aligned_alloc(1, w * h, false); if (!nbuffer) diff --git a/libass/ass_render_api.c b/libass/ass_render_api.c index d3657d3..ee1620a 100644 --- a/libass/ass_render_api.c +++ b/libass/ass_render_api.c @@ -20,7 +20,11 @@ #include "config.h" #include "ass_compat.h" +#include <limits.h> +#include <stdint.h> + #include "ass_render.h" +#include "ass_utils.h" static void ass_reconfigure(ASS_Renderer *priv) { @@ -51,7 +55,7 @@ static void ass_reconfigure(ASS_Renderer *priv) void ass_set_frame_size(ASS_Renderer *priv, int w, int h) { - if (w < 0 || h < 0) + if (w <= 0 || h <= 0 || w > FFMIN(INT_MAX, SIZE_MAX) / h) w = h = 0; if (priv->settings.frame_width != w || priv->settings.frame_height != h) { priv->settings.frame_width = w; @@ -62,7 +66,7 @@ void ass_set_frame_size(ASS_Renderer *priv, int w, int h) void ass_set_storage_size(ASS_Renderer *priv, int w, int h) { - if (w < 0 || h < 0) + if (w <= 0 || h <= 0 || w > FFMIN(INT_MAX, SIZE_MAX) / h) w = h = 0; if (priv->settings.storage_width != w || priv->settings.storage_height != h) { |