summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-01-06 14:42:25 +0000
committerRobin Watts <robin.watts@artifex.com>2012-01-06 14:45:38 +0000
commit6dd9108c5865c1ea2ab0e834f4ae85aa279bcca9 (patch)
treefe3d0a01115cf56f5e9d74c1810094ee2bd8338c
parente504b09e060020c6e7d3478f617a24528de4116d (diff)
downloadmupdf-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.c12
-rw-r--r--fitz/base_geometry.c14
-rw-r--r--fitz/res_path.c20
-rw-r--r--pdf/pdf_annot.c10
-rw-r--r--xps/xps_gradient.c17
-rw-r--r--xps/xps_image.c11
-rw-r--r--xps/xps_path.c2
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;