summaryrefslogtreecommitdiff
path: root/src/cairo-path-stroke-boxes.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-03-24 12:36:41 +0000
committerBryce Harrington <bryce@osg.samsung.com>2017-05-04 17:44:48 -0700
commit91b25005d62fe4ca178f45d349374e42c29a5e11 (patch)
treeb5214845c3b698eee955f45806016fb239baad34 /src/cairo-path-stroke-boxes.c
parenta3cc46d2ccba44a538d05f0c5870b1a82f046350 (diff)
downloadcairo-91b25005d62fe4ca178f45d349374e42c29a5e11.tar.gz
stroker: Check for scaling overflow in computing half line widths
Given a combination of a large scaling matrix and a large line, we can easily generate a half line width that is unrepresentable in our 24.8 fixed-point. This leads to spurious errors later, such as generating negative height boxes, and so asking pixman to fill to infinity. To avoid this, we can check for overflow in calculating the half line with, though we still lack adequate range checking on the final stroke path. References: https://bugs.webkit.org/show_bug.cgi?id=16793 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: magomez@igalia.com Tested-by: Bryce Harrington <bryce@osg.samsung.com> Acked-by: Bryce Harrington <bryce@osg.samsung.com>
Diffstat (limited to 'src/cairo-path-stroke-boxes.c')
-rw-r--r--src/cairo-path-stroke-boxes.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/src/cairo-path-stroke-boxes.c b/src/cairo-path-stroke-boxes.c
index 7f25bf76c..9d3ffe9e3 100644
--- a/src/cairo-path-stroke-boxes.c
+++ b/src/cairo-path-stroke-boxes.c
@@ -98,6 +98,8 @@ _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker,
cairo_antialias_t antialias,
cairo_boxes_t *boxes)
{
+ double half_line_width;
+
/* This special-case rectilinear stroker only supports
* miter-joined lines (not curves) and a translation-only matrix
* (though it could probably be extended to support a matrix with
@@ -127,15 +129,22 @@ _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker,
if (! _cairo_matrix_is_scale (ctm))
return FALSE;
+ half_line_width = stroke_style->line_width / 2.0;
+
+ if (! _cairo_fixed_from_double_safe (&stroker->half_line_x,
+ fabs(ctm->xx) * half_line_width))
+ return FALSE;
+ assert (stroker->half_line_x > 0);
+
+ if (! _cairo_fixed_from_double_safe (&stroker->half_line_y,
+ fabs(ctm->yy) * half_line_width))
+ return FALSE;
+ assert (stroker->half_line_y > 0);
+
stroker->stroke_style = stroke_style;
stroker->ctm = ctm;
stroker->antialias = antialias;
- stroker->half_line_x =
- _cairo_fixed_from_double (fabs(ctm->xx) * stroke_style->line_width / 2.0);
- stroker->half_line_y =
- _cairo_fixed_from_double (fabs(ctm->yy) * stroke_style->line_width / 2.0);
-
stroker->open_sub_path = FALSE;
stroker->segments = stroker->segments_embedded;
stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded);
@@ -287,6 +296,8 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
box.p1.x = b->x;
box.p2.x = a->x;
}
+ assert (box.p1.x < box.p2.x);
+
if (a->y < b->y) {
box.p1.y = a->y;
box.p2.y = b->y;
@@ -294,6 +305,7 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
box.p1.y = b->y;
box.p2.y = a->y;
}
+ assert (box.p1.y < box.p2.y);
status = _cairo_boxes_add (stroker->boxes, stroker->antialias, &box);
if (unlikely (status))
@@ -404,6 +416,8 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
box.p1.x = b->x;
box.p2.x = a->x;
}
+ assert (box.p1.x < box.p2.x);
+
if (a->y < b->y) {
box.p1.y = a->y;
box.p2.y = b->y;
@@ -411,6 +425,7 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
box.p1.y = b->y;
box.p2.y = a->y;
}
+ assert (box.p1.y < box.p2.y);
status = _cairo_boxes_add (stroker->boxes, stroker->antialias, &box);
if (unlikely (status))