summaryrefslogtreecommitdiff
path: root/gs/base
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2015-06-15 13:51:14 +0100
committerRobin Watts <robin.watts@artifex.com>2015-06-15 13:51:14 +0100
commit78b27bf3e1a70699296f41442e767b1d04492b1c (patch)
treed6bc33dfc3efad58134e027592cb20e3579fbafe /gs/base
parent1572afcd641ed003150eec439c7ca16145cd0888 (diff)
downloadghostpdl-78b27bf3e1a70699296f41442e767b1d04492b1c.tar.gz
Bug 695348: Avoid SEGV in interpolated scaler.
Don't use interpolated scaler if calculations have overflowed.
Diffstat (limited to 'gs/base')
-rw-r--r--gs/base/gxipixel.c1
-rw-r--r--gs/base/gxiscale.c15
2 files changed, 16 insertions, 0 deletions
diff --git a/gs/base/gxipixel.c b/gs/base/gxipixel.c
index 188aa3624..29c6327b9 100644
--- a/gs/base/gxipixel.c
+++ b/gs/base/gxipixel.c
@@ -477,6 +477,7 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis,
mty = float2fixed(mat.ty + f) - int2fixed(f);
}
+ /* The next calculation can overflow (see Bug 695348). */
row_extent.x = float2fixed_rounded_boxed(width * mat.xx);
row_extent.y =
(is_fzero(mat.xy) ? fixed_0 :
diff --git a/gs/base/gxiscale.c b/gs/base/gxiscale.c
index 8de9ef6ea..954cb801a 100644
--- a/gs/base/gxiscale.c
+++ b/gs/base/gxiscale.c
@@ -48,6 +48,8 @@
#include "gsicc.h"
#include "gxdevsop.h"
+#include <limits.h> /** for INT_MIN */
+
static void
decode_sample_frac_to_float(gx_image_enum *penum, frac sample_value, gs_client_color *cc, int i);
@@ -100,6 +102,19 @@ gs_image_class_0_interpolate(gx_image_enum * penum)
penum->interpolate = false; /* No need to interpolate and */
return 0; /* causes division by 0 if we try. */
}
+ if (any_abs(penum->dst_width) < 0 || any_abs(penum->dst_height))
+ {
+ /* A calculation has overflowed. Bale */
+ return 0;
+ }
+ if (penum->x_extent.x == INT_MIN || penum->x_extent.x == INT_MAX ||
+ penum->x_extent.y == INT_MIN || penum->x_extent.y == INT_MAX ||
+ penum->y_extent.x == INT_MIN || penum->y_extent.x == INT_MAX ||
+ penum->y_extent.y == INT_MIN || penum->y_extent.y == INT_MAX)
+ {
+ /* A calculation has overflowed. Bale */
+ return 0;
+ }
if ( pcs->cmm_icc_profile_data != NULL ) {
use_icc = true;
}