summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin@peeves.(none)>2013-05-24 07:28:01 -0700
committerRobin Watts <robin.watts@artifex.com>2013-05-27 19:22:24 +0100
commitf59fce4e8effe57adb3a4ba4f615f5028dd4f213 (patch)
treec89b32d37e76e7dc9dcbc92aa391f27f9f10e3b0
parent22cde5d847d90fc9efc86c8862435b751c51430d (diff)
downloadmupdf-f59fce4e8effe57adb3a4ba4f615f5028dd4f213.tar.xz
Bring 2 versions of scaler code into line.
The check for width and height being stupidly large solves a SEGV that shows up while fuzzing.
-rw-r--r--draw/draw_scale.c36
-rw-r--r--draw/draw_simple_scale.c28
2 files changed, 43 insertions, 21 deletions
diff --git a/draw/draw_scale.c b/draw/draw_scale.c
index 83a72584..7db0fe6c 100644
--- a/draw/draw_scale.c
+++ b/draw/draw_scale.c
@@ -1261,6 +1261,34 @@ fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float
DBUG(("Scale: (%d,%d) to (%g,%g) at (%g,%g)\n",src->w,src->h,w,h,x,y));
+ /* Avoid extreme scales where overflows become problematic. */
+ if (w > (1<<24) || h > (1<<24) || w < -(1<<24) || h < -(1<<24))
+ return NULL;
+
+ /* Clamp small ranges of w and h */
+ if (w <= -1)
+ {
+ }
+ else if (w < 0)
+ {
+ w = -1;
+ }
+ else if (w < 1)
+ {
+ w = 1;
+ }
+ if (h <= -1)
+ {
+ }
+ else if (h < 0)
+ {
+ h = -1;
+ }
+ else if (h < 1)
+ {
+ h = 1;
+ }
+
/* Find the destination bbox, width/height, and sub pixel offset,
* allowing for whether we're flipping or not. */
/* The (x,y) position given describes where the top left corner
@@ -1280,7 +1308,7 @@ fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float
* y is always R.ymax - r.ymax.
*/
/* dst_x_int is calculated to be the left of the scaled image, and
- * x (the sub_pixel_offset) is the distance in from either the left
+ * x (the sub pixel offset) is the distance in from either the left
* or right pixel expanded edge. */
flip_x = (w < 0);
if (flip_x)
@@ -1299,11 +1327,11 @@ fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float
x -= (float)dst_x_int;
dst_w_int = (int)ceilf(x + w);
}
- flip_y = (h < 0);
/* dst_y_int is calculated to be the top of the scaled image, and
* y (the sub pixel offset) is the distance in from either the top
* or bottom pixel expanded edge.
*/
+ flip_y = (h < 0);
if (flip_y)
{
float tmp;
@@ -1313,7 +1341,9 @@ fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float
dst_h_int = (int)tmp;
y = tmp - y;
dst_h_int -= dst_y_int;
- } else {
+ }
+ else
+ {
dst_y_int = floorf(y);
y -= (float)dst_y_int;
dst_h_int = (int)ceilf(y + h);
diff --git a/draw/draw_simple_scale.c b/draw/draw_simple_scale.c
index 811bae13..9bf6857f 100644
--- a/draw/draw_simple_scale.c
+++ b/draw/draw_simple_scale.c
@@ -305,16 +305,8 @@ add_weight(fz_weights *weights, int j, int i, fz_scale_filter *filter,
weight = (int)(256*f+0.5f);
/* Ensure i is in range */
- if (i < 0)
- {
- i = 0;
+ if (i < 0 || i >= src_w)
return;
- }
- else if (i >= src_w)
- {
- i = src_w-1;
- return;
- }
if (weight == 0)
{
/* We add a fudge factor here to allow for extreme downscales
@@ -1267,13 +1259,13 @@ fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float
/* Find the destination bbox, width/height, and sub pixel offset,
* allowing for whether we're flipping or not. */
- /* The (x,y) position given describes where the top left corner of the
- * source image should be mapped to (i.e. where (0,0) in image space ends
- * up). Also there are differences in the way we scale horizontally and
- * vertically. When scaling rows horizontally, we always read forwards
- * through the source, and store either forwards or in reverse as required.
- * When scaling vertically, we always store out forwards, but may feed
- * source rows in in a different order.
+ /* The (x,y) position given describes where the top left corner
+ * of the source image should be mapped to (i.e. where (0,0) in image
+ * space ends up). Also there are differences in the way we scale
+ * horizontally and vertically. When scaling rows horizontally, we
+ * always read forwards through the source, and store either forwards
+ * or in reverse as required. When scaling vertically, we always store
+ * out forwards, but may feed source rows in in a different order.
*
* Consider the image rectangle 'r' to which the image is mapped,
* and the (possibly) larger rectangle 'R', given by expanding 'r' to
@@ -1284,7 +1276,7 @@ fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float
* y is always R.ymax - r.ymax.
*/
/* dst_x_int is calculated to be the left of the scaled image, and
- * x (the sub_pixel_offset) is the distance in from either the left
+ * x (the sub pixel offset) is the distance in from either the left
* or right pixel expanded edge. */
flip_x = (w < 0);
if (flip_x)
@@ -1304,7 +1296,7 @@ fz_scale_pixmap_cached(fz_context *ctx, fz_pixmap *src, float x, float y, float
dst_w_int = (int)ceilf(x + w);
}
/* dst_y_int is calculated to be the top of the scaled image, and
- * y (the sub_pixel_offset) is the distance in from either the top
+ * y (the sub pixel offset) is the distance in from either the top
* or bottom pixel expanded edge.
*/
flip_y = (h < 0);