From f59fce4e8effe57adb3a4ba4f615f5028dd4f213 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Fri, 24 May 2013 07:28:01 -0700 Subject: 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. --- draw/draw_scale.c | 36 +++++++++++++++++++++++++++++++++--- draw/draw_simple_scale.c | 28 ++++++++++------------------ 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); -- cgit v1.2.3