summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-13 21:06:10 +0100
committerwm4 <wm4@nowhere>2014-11-13 21:54:12 +0100
commit8536eaa5cc4652e4c360bc5ab5f1c3e72f6256fa (patch)
treed1bd6e7ff3da8063c8ac0a486208bcaf3edd901e
parent901c5bf00abbe738a5665662e6a3b44f91c4d6d4 (diff)
downloadlibass-8536eaa5cc4652e4c360bc5ab5f1c3e72f6256fa.tar.bz2
libass-8536eaa5cc4652e4c360bc5ab5f1c3e72f6256fa.tar.xz
Check for another overflow in blur code
-rw-r--r--libass/ass_bitmap.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c
index 2fbca79..76a0703 100644
--- a/libass/ass_bitmap.c
+++ b/libass/ass_bitmap.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <stdbool.h>
#include <assert.h>
#include <ft2build.h>
#include FT_GLYPH_H
@@ -39,7 +40,7 @@
static const unsigned base = 256;
struct ass_synth_priv {
- int tmp_w, tmp_h;
+ size_t tmp_allocated;
void *tmp;
int g_r;
@@ -121,31 +122,32 @@ static int generate_tables(ASS_SynthPriv *priv, double radius)
return 0;
}
-static void resize_tmp(ASS_SynthPriv *priv, int w, int h)
+static bool resize_tmp(ASS_SynthPriv *priv, int w, int h)
{
- if (priv->tmp_w >= w && priv->tmp_h >= h)
- return;
- if (priv->tmp_w == 0)
- priv->tmp_w = 64;
- if (priv->tmp_h == 0)
- priv->tmp_h = 64;
- while (priv->tmp_w < w)
- priv->tmp_w *= 2;
- while (priv->tmp_h < h)
- priv->tmp_h *= 2;
+ if (w > SIZE_MAX / sizeof(unsigned) / h)
+ return false;
+ size_t needed = sizeof(unsigned) * w * h;
+ if (priv->tmp && priv->tmp_allocated >= needed)
+ return true;
+ if (needed >= SIZE_MAX / 2)
+ return false;
+
ass_aligned_free(priv->tmp);
- priv->tmp =
- ass_aligned_alloc(32, (priv->tmp_w + 1) * priv->tmp_h * sizeof(unsigned));
+ priv->tmp_allocated = FFMAX(needed, priv->tmp_allocated * 2);
+ priv->tmp = ass_aligned_alloc(32, priv->tmp_allocated);
+ if (!priv->tmp)
+ return false;
+ return true;
}
void ass_synth_blur(ASS_SynthPriv *priv_blur, int opaque_box, int be,
double blur_radius, Bitmap *bm_g, Bitmap *bm_o)
{
if(blur_radius > 0.0 || be){
- if (bm_o)
- resize_tmp(priv_blur, bm_o->w, bm_o->h);
- if (!bm_o || opaque_box)
- resize_tmp(priv_blur, bm_g->w, bm_g->h);
+ if (bm_o && !resize_tmp(priv_blur, bm_o->w, bm_o->h))
+ return;
+ if ((!bm_o || opaque_box) && !resize_tmp(priv_blur, bm_g->w, bm_g->h))
+ return;
}
// Apply box blur (multiple passes, if requested)