|
|
159db5 |
From 19f9685dbff7d1f929c61cf99188df917a18811d Mon Sep 17 00:00:00 2001
|
|
|
159db5 |
From: Benjamin Otte <otte@redhat.com>
|
|
|
159db5 |
Date: Sat, 19 Sep 2015 21:24:34 +0200
|
|
|
159db5 |
Subject: [PATCH] pixops: Fail make_weights functions on OOM
|
|
|
159db5 |
|
|
|
159db5 |
The weights could grow very large under certain circumstances, in
|
|
|
159db5 |
particular in security-relevant conditions, including the testsuite.
|
|
|
159db5 |
By allowing the weight allocation to fail, this can be worked around.
|
|
|
159db5 |
|
|
|
159db5 |
https://bugzilla.gnome.org/show_bug.cgi?id=754387
|
|
|
159db5 |
---
|
|
|
159db5 |
gdk-pixbuf/pixops/pixops.c | 75 +++++++++++++++++++++++++++++++++-------------
|
|
|
159db5 |
1 file changed, 55 insertions(+), 20 deletions(-)
|
|
|
159db5 |
|
|
|
159db5 |
diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
|
|
|
159db5 |
index e41b286..4cdb5df 100644
|
|
|
159db5 |
--- a/gdk-pixbuf/pixops/pixops.c
|
|
|
159db5 |
+++ b/gdk-pixbuf/pixops/pixops.c
|
|
|
159db5 |
@@ -1478,15 +1478,19 @@ pixops_process (guchar *dest_buf,
|
|
|
159db5 |
/* Compute weights for reconstruction by replication followed by
|
|
|
159db5 |
* sampling with a box filter
|
|
|
159db5 |
*/
|
|
|
159db5 |
-static void
|
|
|
159db5 |
+static gboolean
|
|
|
159db5 |
tile_make_weights (PixopsFilterDimension *dim,
|
|
|
159db5 |
double scale)
|
|
|
159db5 |
{
|
|
|
159db5 |
int n = ceil (1 / scale + 1);
|
|
|
159db5 |
- double *pixel_weights = g_malloc_n (sizeof (double) * SUBSAMPLE, n);
|
|
|
159db5 |
+ double *pixel_weights;
|
|
|
159db5 |
int offset;
|
|
|
159db5 |
int i;
|
|
|
159db5 |
|
|
|
159db5 |
+ pixel_weights = g_try_malloc_n (sizeof (double) * SUBSAMPLE, n);
|
|
|
159db5 |
+ if (pixel_weights == NULL)
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
+
|
|
|
159db5 |
dim->n = n;
|
|
|
159db5 |
dim->offset = 0;
|
|
|
159db5 |
dim->weights = pixel_weights;
|
|
|
159db5 |
@@ -1514,13 +1518,15 @@ tile_make_weights (PixopsFilterDimension *dim,
|
|
|
159db5 |
}
|
|
|
159db5 |
}
|
|
|
159db5 |
}
|
|
|
159db5 |
+
|
|
|
159db5 |
+ return TRUE;
|
|
|
159db5 |
}
|
|
|
159db5 |
|
|
|
159db5 |
/* Compute weights for a filter that, for minification
|
|
|
159db5 |
* is the same as 'tiles', and for magnification, is bilinear
|
|
|
159db5 |
* reconstruction followed by a sampling with a delta function.
|
|
|
159db5 |
*/
|
|
|
159db5 |
-static void
|
|
|
159db5 |
+static gboolean
|
|
|
159db5 |
bilinear_magnify_make_weights (PixopsFilterDimension *dim,
|
|
|
159db5 |
double scale)
|
|
|
159db5 |
{
|
|
|
159db5 |
@@ -1541,7 +1547,9 @@ bilinear_magnify_make_weights (PixopsFilterDimension *dim,
|
|
|
159db5 |
}
|
|
|
159db5 |
|
|
|
159db5 |
dim->n = n;
|
|
|
159db5 |
- dim->weights = g_malloc_n (sizeof (double) * SUBSAMPLE, n);
|
|
|
159db5 |
+ dim->weights = g_try_malloc_n (sizeof (double) * SUBSAMPLE, n);
|
|
|
159db5 |
+ if (dim->weights == NULL)
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
|
|
|
159db5 |
pixel_weights = dim->weights;
|
|
|
159db5 |
|
|
|
159db5 |
@@ -1581,6 +1589,8 @@ bilinear_magnify_make_weights (PixopsFilterDimension *dim,
|
|
|
159db5 |
}
|
|
|
159db5 |
}
|
|
|
159db5 |
}
|
|
|
159db5 |
+
|
|
|
159db5 |
+ return TRUE;
|
|
|
159db5 |
}
|
|
|
159db5 |
|
|
|
159db5 |
/* Computes the integral from b0 to b1 of
|
|
|
159db5 |
@@ -1627,15 +1637,19 @@ linear_box_half (double b0, double b1)
|
|
|
159db5 |
/* Compute weights for reconstructing with bilinear
|
|
|
159db5 |
* interpolation, then sampling with a box filter
|
|
|
159db5 |
*/
|
|
|
159db5 |
-static void
|
|
|
159db5 |
+static gboolean
|
|
|
159db5 |
bilinear_box_make_weights (PixopsFilterDimension *dim,
|
|
|
159db5 |
double scale)
|
|
|
159db5 |
{
|
|
|
159db5 |
int n = ceil (1/scale + 3.0);
|
|
|
159db5 |
- double *pixel_weights = g_malloc_n (sizeof (double) * SUBSAMPLE, n);
|
|
|
159db5 |
+ double *pixel_weights;
|
|
|
159db5 |
double w;
|
|
|
159db5 |
int offset, i;
|
|
|
159db5 |
|
|
|
159db5 |
+ pixel_weights = g_malloc_n (sizeof (double) * SUBSAMPLE, n);
|
|
|
159db5 |
+ if (pixel_weights == NULL)
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
+
|
|
|
159db5 |
dim->offset = -1.0;
|
|
|
159db5 |
dim->n = n;
|
|
|
159db5 |
dim->weights = pixel_weights;
|
|
|
159db5 |
@@ -1653,9 +1667,11 @@ bilinear_box_make_weights (PixopsFilterDimension *dim,
|
|
|
159db5 |
*(pixel_weights++) = w * scale;
|
|
|
159db5 |
}
|
|
|
159db5 |
}
|
|
|
159db5 |
+
|
|
|
159db5 |
+ return TRUE;
|
|
|
159db5 |
}
|
|
|
159db5 |
|
|
|
159db5 |
-static void
|
|
|
159db5 |
+static gboolean
|
|
|
159db5 |
make_weights (PixopsFilter *filter,
|
|
|
159db5 |
PixopsInterpType interp_type,
|
|
|
159db5 |
double scale_x,
|
|
|
159db5 |
@@ -1664,23 +1680,39 @@ make_weights (PixopsFilter *filter,
|
|
|
159db5 |
switch (interp_type)
|
|
|
159db5 |
{
|
|
|
159db5 |
case PIXOPS_INTERP_NEAREST:
|
|
|
159db5 |
+ default:
|
|
|
159db5 |
g_assert_not_reached ();
|
|
|
159db5 |
- break;
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
|
|
|
159db5 |
case PIXOPS_INTERP_TILES:
|
|
|
159db5 |
- tile_make_weights (&filter->x, scale_x);
|
|
|
159db5 |
- tile_make_weights (&filter->y, scale_y);
|
|
|
159db5 |
- break;
|
|
|
159db5 |
+ if (!tile_make_weights (&filter->x, scale_x))
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
+ if (!tile_make_weights (&filter->y, scale_y))
|
|
|
159db5 |
+ {
|
|
|
159db5 |
+ g_free (filter->x.weights);
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
+ }
|
|
|
159db5 |
+ return TRUE;
|
|
|
159db5 |
|
|
|
159db5 |
case PIXOPS_INTERP_BILINEAR:
|
|
|
159db5 |
- bilinear_magnify_make_weights (&filter->x, scale_x);
|
|
|
159db5 |
- bilinear_magnify_make_weights (&filter->y, scale_y);
|
|
|
159db5 |
- break;
|
|
|
159db5 |
+ if (!bilinear_magnify_make_weights (&filter->x, scale_x))
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
+ if (!bilinear_magnify_make_weights (&filter->y, scale_y))
|
|
|
159db5 |
+ {
|
|
|
159db5 |
+ g_free (filter->x.weights);
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
+ }
|
|
|
159db5 |
+ return TRUE;
|
|
|
159db5 |
|
|
|
159db5 |
case PIXOPS_INTERP_HYPER:
|
|
|
159db5 |
- bilinear_box_make_weights (&filter->x, scale_x);
|
|
|
159db5 |
- bilinear_box_make_weights (&filter->y, scale_y);
|
|
|
159db5 |
- break;
|
|
|
159db5 |
+ if (!bilinear_box_make_weights (&filter->x, scale_x))
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
+ if (!bilinear_box_make_weights (&filter->y, scale_y))
|
|
|
159db5 |
+ {
|
|
|
159db5 |
+ g_free (filter->x.weights);
|
|
|
159db5 |
+ return FALSE;
|
|
|
159db5 |
+ }
|
|
|
159db5 |
+ return TRUE;
|
|
|
159db5 |
}
|
|
|
159db5 |
}
|
|
|
159db5 |
|
|
|
159db5 |
@@ -1735,7 +1767,8 @@ _pixops_composite_color_real (guchar *dest_buf,
|
|
|
159db5 |
}
|
|
|
159db5 |
|
|
|
159db5 |
filter.overall_alpha = overall_alpha / 255.;
|
|
|
159db5 |
- make_weights (&filter, interp_type, scale_x, scale_y);
|
|
|
159db5 |
+ if (!make_weights (&filter, interp_type, scale_x, scale_y))
|
|
|
159db5 |
+ return;
|
|
|
159db5 |
|
|
|
159db5 |
#ifdef USE_MMX
|
|
|
159db5 |
if (filter.x.n == 2 && filter.y.n == 2 &&
|
|
|
159db5 |
@@ -1890,7 +1923,8 @@ _pixops_composite_real (guchar *dest_buf,
|
|
|
159db5 |
}
|
|
|
159db5 |
|
|
|
159db5 |
filter.overall_alpha = overall_alpha / 255.;
|
|
|
159db5 |
- make_weights (&filter, interp_type, scale_x, scale_y);
|
|
|
159db5 |
+ if (!make_weights (&filter, interp_type, scale_x, scale_y))
|
|
|
159db5 |
+ return;
|
|
|
159db5 |
|
|
|
159db5 |
if (filter.x.n == 2 && filter.y.n == 2 && dest_channels == 4 &&
|
|
|
159db5 |
src_channels == 4 && src_has_alpha && !dest_has_alpha)
|
|
|
159db5 |
@@ -2297,7 +2331,8 @@ _pixops_scale_real (guchar *dest_buf,
|
|
|
159db5 |
}
|
|
|
159db5 |
|
|
|
159db5 |
filter.overall_alpha = 1.0;
|
|
|
159db5 |
- make_weights (&filter, interp_type, scale_x, scale_y);
|
|
|
159db5 |
+ if (!make_weights (&filter, interp_type, scale_x, scale_y))
|
|
|
159db5 |
+ return;
|
|
|
159db5 |
|
|
|
159db5 |
if (filter.x.n == 2 && filter.y.n == 2 && dest_channels == 3 && src_channels == 3)
|
|
|
159db5 |
{
|
|
|
159db5 |
--
|
|
|
159db5 |
2.5.2
|
|
|
159db5 |
|