diff options
author | Robin Watts <robin.watts@artifex.com> | 2012-01-06 14:42:25 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2012-01-06 14:45:38 +0000 |
commit | 6dd9108c5865c1ea2ab0e834f4ae85aa279bcca9 (patch) | |
tree | fe3d0a01115cf56f5e9d74c1810094ee2bd8338c | |
parent | e504b09e060020c6e7d3478f617a24528de4116d (diff) | |
download | mupdf-6dd9108c5865c1ea2ab0e834f4ae85aa279bcca9.tar.xz |
Various fixes to avoid arithmetic problems.
Various fixes to avoid overflow problems, division by zeros, use
of uninitialised variables etc. All from/suggested by Zenikos patch.
-rw-r--r-- | draw/draw_edge.c | 12 | ||||
-rw-r--r-- | fitz/base_geometry.c | 14 | ||||
-rw-r--r-- | fitz/res_path.c | 20 | ||||
-rw-r--r-- | pdf/pdf_annot.c | 10 | ||||
-rw-r--r-- | xps/xps_gradient.c | 17 | ||||
-rw-r--r-- | xps/xps_image.c | 11 | ||||
-rw-r--r-- | xps/xps_path.c | 2 |
7 files changed, 57 insertions, 29 deletions
diff --git a/draw/draw_edge.c b/draw/draw_edge.c index 76187bef..2cc6ddbe 100644 --- a/draw/draw_edge.c +++ b/draw/draw_edge.c @@ -261,13 +261,13 @@ clip_lerp_x(int val, int m, int x0, int y0, int x1, int y1, int *out) if (v1out) { - *out = y0 + (y1 - y0) * (val - x0) / (x1 - x0); + *out = y0 + (int)(((float)(y1 - y0)) * (val - x0) / (x1 - x0)); return LEAVE; } else { - *out = y1 + (y0 - y1) * (val - x1) / (x0 - x1); + *out = y1 + (int)(((float)(y0 - y1)) * (val - x1) / (x0 - x1)); return ENTER; } } @@ -349,10 +349,10 @@ fz_insert_gel(fz_gel *gel, float fx0, float fy0, float fx1, float fy1) fy0 = floorf(fy0 * fz_aa_vscale); fy1 = floorf(fy1 * fz_aa_vscale); - x0 = CLAMP(fx0, BBOX_MIN, BBOX_MAX); - y0 = CLAMP(fy0, BBOX_MIN, BBOX_MAX); - x1 = CLAMP(fx1, BBOX_MIN, BBOX_MAX); - y1 = CLAMP(fy1, BBOX_MIN, BBOX_MAX); + x0 = CLAMP(fx0, BBOX_MIN * fz_aa_hscale, BBOX_MAX * fz_aa_hscale); + y0 = CLAMP(fy0, BBOX_MIN * fz_aa_vscale, BBOX_MAX * fz_aa_vscale); + x1 = CLAMP(fx1, BBOX_MIN * fz_aa_hscale, BBOX_MAX * fz_aa_hscale); + y1 = CLAMP(fy1, BBOX_MIN * fz_aa_vscale, BBOX_MAX * fz_aa_vscale); d = clip_lerp_y(gel->clip.y0, 0, x0, y0, x1, y1, &v); if (d == OUTSIDE) return; diff --git a/fitz/base_geometry.c b/fitz/base_geometry.c index 00a85c9b..4f9ef8b6 100644 --- a/fitz/base_geometry.c +++ b/fitz/base_geometry.c @@ -153,10 +153,16 @@ fz_bbox fz_round_rect(fz_rect f) { fz_bbox i; - i.x0 = floorf(f.x0 + 0.001f); /* adjust by 0.001 to compensate for precision errors */ - i.y0 = floorf(f.y0 + 0.001f); - i.x1 = ceilf(f.x1 - 0.001f); - i.y1 = ceilf(f.y1 - 0.001f); + /* adjust by 0.001 to compensate for precision errors */ + f.x0 = floorf(f.x0 + 0.001f); + f.y0 = floorf(f.y0 + 0.001f); + f.x1 = ceilf(f.x1 - 0.001f); + f.y1 = ceilf(f.y1 - 0.001f); +#define SAFE_INT(f) ((f > INT_MAX) ? INT_MAX : ((f < INT_MIN) ? INT_MIN : (int)f)) + i.x0 = SAFE_INT(f.x0); + i.y0 = SAFE_INT(f.y0); + i.x1 = SAFE_INT(f.x1); + i.y1 = SAFE_INT(f.y1); return i; } diff --git a/fitz/res_path.c b/fitz/res_path.c index bf61cff6..d8838899 100644 --- a/fitz/res_path.c +++ b/fitz/res_path.c @@ -147,17 +147,19 @@ fz_rect fz_bound_path(fz_path *path, fz_stroke_state *stroke, fz_matrix ctm) { fz_point p; - fz_rect r = fz_empty_rect; + fz_rect r; int i = 0; - if (path->len) - { - p.x = path->items[1].v; - p.y = path->items[2].v; - p = fz_transform_point(ctm, p); - r.x0 = r.x1 = p.x; - r.y0 = r.y1 = p.y; - } + /* If the path is empty, return the empty rectangle here - don't wait + * for it to be expanded in the stroked case below. */ + if (path->len == 0) + return fz_empty_rect; + + p.x = path->items[1].v; + p.y = path->items[2].v; + p = fz_transform_point(ctm, p); + r.x0 = r.x1 = p.x; + r.y0 = r.y1 = p.y; while (i < path->len) { diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c index 228a214e..f7e7f081 100644 --- a/pdf/pdf_annot.c +++ b/pdf/pdf_annot.c @@ -328,8 +328,14 @@ pdf_transform_annot(pdf_annot *annot) float w, h, x, y; bbox = fz_transform_rect(matrix, bbox); - w = (rect.x1 - rect.x0) / (bbox.x1 - bbox.x0); - h = (rect.y1 - rect.y0) / (bbox.y1 - bbox.y0); + if (bbox.x1 == bbox.x0) + w = 0; + else + w = (rect.x1 - rect.x0) / (bbox.x1 - bbox.x0); + if (bbox.y1 == bbox.y0) + h = 0; + else + h = (rect.y1 - rect.y0) / (bbox.y1 - bbox.y0); x = rect.x0 - bbox.x0; y = rect.y0 - bbox.y0; diff --git a/xps/xps_gradient.c b/xps/xps_gradient.c index 8bdc3cc5..7533c4d3 100644 --- a/xps/xps_gradient.c +++ b/xps/xps_gradient.c @@ -312,6 +312,11 @@ xps_draw_radial_gradient(xps_document *doc, fz_matrix ctm, char *radius_x_att = xml_att(root, "RadiusX"); char *radius_y_att = xml_att(root, "RadiusY"); + x0 = y0 = 0.0; + x1 = y1 = 1.0; + xrad = 1.0; + yrad = 1.0; + if (origin_att) sscanf(origin_att, "%g,%g", &x0, &y0); if (center_att) @@ -322,11 +327,15 @@ xps_draw_radial_gradient(xps_document *doc, fz_matrix ctm, yrad = fz_atof(radius_y_att); /* scale the ctm to make ellipses */ - ctm = fz_concat(fz_scale(1, yrad / xrad), ctm); + if (xrad != 0.0) + ctm = fz_concat(fz_scale(1, yrad / xrad), ctm); - invscale = xrad / yrad; - y0 = y0 * invscale; - y1 = y1 * invscale; + if (yrad != 0.0) + { + invscale = xrad / yrad; + y0 = y0 * invscale; + y1 = y1 * invscale; + } r0 = 0; r1 = xrad; diff --git a/xps/xps_image.c b/xps/xps_image.c index 6ba017da..85a467af 100644 --- a/xps/xps_image.c +++ b/xps/xps_image.c @@ -28,9 +28,14 @@ xps_paint_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base xml_element *root, void *vimage) { fz_pixmap *pixmap = vimage; - float xs = pixmap->w * 96 / pixmap->xres; - float ys = pixmap->h * 96 / pixmap->yres; - fz_matrix im = fz_scale(xs, -ys); + float xs, ys; + fz_matrix im; + + if (pixmap->xres == 0 || pixmap->yres == 0) + return; + xs = pixmap->w * 96 / pixmap->xres; + ys = pixmap->h * 96 / pixmap->yres; + im = fz_scale(xs, -ys); im.f = ys; ctm = fz_concat(im, ctm); fz_fill_image(doc->dev, pixmap, ctm, doc->opacity[doc->opacity_top]); diff --git a/xps/xps_path.c b/xps/xps_path.c index ead2c7fa..402ca532 100644 --- a/xps/xps_path.c +++ b/xps/xps_path.c @@ -145,7 +145,7 @@ xps_draw_arc(fz_context *doc, fz_path *path, /* F.6.6.1 -- ensure radii are positive and non-zero */ rx = fabsf(rx); ry = fabsf(ry); - if (rx < 0.001f || ry < 0.001f) + if (rx < 0.001f || ry < 0.001f || (x1 == x2 && y1 == y2)) { fz_lineto(doc, path, x2, y2); return; |