Bug 90120

Summary: Image compositor can pass invalid coordinates to pixman_fill()
Product: cairo Reporter: Federico Mena-Quintero <federico>
Component: generalAssignee: Chris Wilson <chris>
Status: RESOLVED MOVED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: cairo-validate-pixman-fill.patch
Preliminary stroke validation

Description Federico Mena-Quintero 2015-04-20 21:34:18 UTC
See https://bugzilla.gnome.org/show_bug.cgi?id=744391 for where this comes from.

Summary: librsvg gets an SVG generated through fuzz-testing, and passes big coordinates that give problems to Cairo.  In turn, Cairo ends up passing invalid coordinates to pixman_fill(), which does an out-of-bounds write.

Pixman doesn't validate the arguments passed to pixman_fill().

Given that Cairo's problems with big coordinates and fixed-point overflow are Hard To Fix(tm), we can make Cairo at least responsible for not passing invalid coordinates to pixman's low-level machinery.

The attached patch takes care of the call to pixman_fill() from this particular code path.  I haven't gotten reports of other invalid calls to pixman_fill() from Cairo/librsvg.
Comment 1 Federico Mena-Quintero 2015-04-20 21:36:40 UTC
Created attachment 115238 [details]
cairo-validate-pixman-fill.patch
Comment 2 Federico Mena-Quintero 2015-04-20 21:46:39 UTC
For reference, this is the top of the backtrace when the invalid write happens:

#0  0x000000000b530d04 in sse2_fill (imp=0xf5e2390, bits=0x12461330, stride=80, bpp=32, x=1, y=1, width=18, height=-14, filler=4294901760) at pixman-sse2.c:3394
#1  0x000000000b497319 in _pixman_implementation_fill (imp=0xf5e2390, bits=0x12461330, stride=20, bpp=32, x=1, y=1, width=18, height=-2, filler=4294901760) at pixman-implementation.c:277
#2  0x000000000b2abced in pixman_fill (bits=0x12461330, stride=20, bpp=32, x=1, y=1, width=18, height=-2, filler=4294901760) at pixman.c:766
#3  0x0000000006c3895d in fill_boxes (_dst=0x12461730, op=CAIRO_OPERATOR_SOURCE, color=0x7feffeee8, boxes=0x7feffe990) at cairo-image-compositor.c:349
#4  0x0000000006c84450 in composite_aligned_boxes (compositor=0x6f72dc0 <spans.11385>, extents=0x7feffedf0, boxes=0x7feffe990) at cairo-spans-compositor.c:619
#5  0x0000000006c84dbd in clip_and_composite_boxes (compositor=0x6f72dc0 <spans.11385>, extents=0x7feffedf0, boxes=0x7feffe990) at cairo-spans-compositor.c:873
#6  0x0000000006c852d1 in _cairo_spans_compositor_stroke (_compositor=0x6f72dc0 <spans.11385>, extents=0x7feffedf0, path=0x1245f538, style=0x7fefff210, ctm=0x12464a40, ctm_inverse=0x12464a70, tolerance=0.10000000000000001, 
    antialias=CAIRO_ANTIALIAS_DEFAULT) at cairo-spans-compositor.c:1029
#7  0x0000000006c29d02 in _cairo_compositor_stroke (compositor=0x6f72dc0 <spans.11385>, surface=0x12461730, op=CAIRO_OPERATOR_OVER, source=0x7fefff240, path=0x1245f538, style=0x7fefff210, ctm=0x12464a40, ctm_inverse=0x12464a70, 
    tolerance=0.10000000000000001, antialias=CAIRO_ANTIALIAS_DEFAULT, clip=0x0) at cairo-compositor.c:157
#8  0x0000000006c4162f in _cairo_image_surface_stroke (abstract_surface=0x12461730, op=CAIRO_OPERATOR_OVER, source=0x7fefff240, path=0x1245f538, style=0x7fefff210, ctm=0x12464a40, ctm_inverse=0x12464a70, tolerance=0.10000000000000001, 
    antialias=CAIRO_ANTIALIAS_DEFAULT, clip=0x0) at cairo-image-surface.c:961
#9  0x0000000006c8aad8 in _cairo_surface_stroke (surface=0x12461730, op=CAIRO_OPERATOR_OVER, source=0x7fefff240, path=0x1245f538, stroke_style=0x7fefff210, ctm=0x12464a40, ctm_inverse=0x12464a70, tolerance=0.10000000000000001, 
    antialias=CAIRO_ANTIALIAS_DEFAULT, clip=0x0) at cairo-surface.c:2210
#10 0x0000000006c33fd3 in _cairo_gstate_stroke (gstate=0x12464950, path=0x1245f538) at cairo-gstate.c:1185
#11 0x0000000006c2dbad in _cairo_default_context_stroke (abstract_cr=0x1245f1d0) at cairo-default-context.c:1013
#12 0x0000000006c225e5 in INT_cairo_stroke (cr=0x1245f1d0) at cairo.c:2146
#13 0x0000000004e5ae8e in rsvg_cairo_render_path (ctx=0x12463af0, path=<optimized out>) at rsvg-cairo-draw.c:549
Comment 3 Federico Mena-Quintero 2015-04-20 21:47:58 UTC
Note frame #2 above, where pixman_fill() gets passed height=-2
Comment 4 Chris Wilson 2015-04-20 21:58:42 UTC
I doubt that you have a (uint32_t)-2 tall surface, so there is a much earlier bug where this manages to evade clipping.
Comment 5 Federico Mena-Quintero 2015-04-20 23:41:33 UTC
(In reply to Chris Wilson from comment #4)
> I doubt that you have a (uint32_t)-2 tall surface, so there is a much
> earlier bug where this manages to evade clipping.

I've just made the gnome.org bug visible; it was marked as a security bug, but it's not easily exploitable.

I'd love to fix the root cause (Cairo not dealing with big coordinates correctly), but that's a much bigger problem than putting a safety valve.  Pixman should do it, or at least document the fact that it doesn't.
Comment 6 Bryce Harrington 2015-04-21 02:11:05 UTC
If I understand this particular bug correctly, the issue is that librsvg can pass in stroke widths that exceed the practical limits that cairo can handle.

Checking the parameters before making the pixman call sounds like it addresses the crash, but has two problems - first, since this bit of code is pretty low level there may be performance issues; second, as Chris said the problem starts higher up so this may paper over where the garbage data causes one crash, but leaves the garbage data in there to cause other problems that might be less obvious than crashes (e.g. mis-rendering).

Looking higher up the stack, _cairo_surface_fill_stroke may be a better place to do the checking.  It already is validating surfaces and such, so would make sense for it to check for this condition too.  I'm not sure what that code would look like, though.

But we may be able to address it even earlier; the garbage data I assume comes from the excessively large line stroke width generated by the fuzz tester and thus I assume is getting set via a call to cairo_set_line_width():

rsvg_cairo_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path)
{
    ...
    cairo_set_line_width (cr, _rsvg_css_normalize_length (&state->stroke_width, ctx, 'h'));  // <-- garbage-in?
    cairo_set_miter_limit (cr, state->miter_limit);
    cairo_set_line_cap (cr, (cairo_line_cap_t) state->cap);
    cairo_set_line_join (cr, (cairo_line_join_t) state->join);
    cairo_set_dash (cr, state->dash.dash, state->dash.n_dash,
                    _rsvg_css_normalize_length (&state->dash.offset, ctx, 'o'));
    ...
    cairo_stroke (cr); // !CRASH!

cairo_set_line_width() already does some input checking by clamping underrun widths to 0.  This could be made to similarly clamp maximum values, or flag an error via _cairo_set_error.  It's unclear what that maximum should be though; something smaller than 4294967294 presumably.

Even if we add a check to cairo_set_line_width(), it is possible that scaling or other operations subsequent to that could modify things to invalid sizes.  So it makes sense to also check in _cairo_surface_fill_stroke.
Comment 7 Chris Wilson 2015-04-21 07:01:44 UTC
Created attachment 115240 [details] [review]
Preliminary stroke validation

Imo, the important thing here, if we take the input validation path, is to only apply it at the boundary of the fixed point representation i.e. so that we only reject extreme values when rastering, but pass through to vector backends (or apply their own range checking).

However, extreme line_width has a very simple interpretation and I think it would be better for cairo to have a slow-but-safe rasteriser. Detecting when the input path and style will produce illegal fixed point values and switching to a double representation will allow us to generate output without crashing with a slight loss of precision.
Comment 8 Federico Mena-Quintero 2015-04-22 23:15:14 UTC
(In reply to Chris Wilson from comment #7)
> Created attachment 115240 [details] [review] [review]
> Preliminary stroke validation

This is really nice!  It fixes the problem very cleanly - valgrind shows no problems with the fuzzed file.

(And thanks for making me aware of CAIRO_STATUS_INVALID_SIZE; hopefully we'll have a lot more of it in the future :)

> Imo, the important thing here, if we take the input validation path, is to
> only apply it at the boundary of the fixed point representation i.e. so that
> we only reject extreme values when rastering, but pass through to vector
> backends (or apply their own range checking).

Agreed.

> However, extreme line_width has a very simple interpretation and I think it
> would be better for cairo to have a slow-but-safe rasteriser. Detecting when
> the input path and style will produce illegal fixed point values and
> switching to a double representation will allow us to generate output
> without crashing with a slight loss of precision.

This would be nice in the get-everything-absolutely-correct sense of things, but I'm not very concerned about it.  If the caller gets a meaningful error like CAIRO_STATUS_INVALID_SIZE, then it will know that something is amiss.

Chris, since you just put your foot into the rabbit hole :)  May I interest you in another fixed-point overflow thing?  This goes back to the old bugs #20091 and #39096.  Using this fuzzed svg

<svg>
  <defs>
    <clipPath id="clipper">
      <rect y="19" width="2" height="2" />
      <rect width="18446744073709551616" height="29" />
    </clipPath>
  </defs>
  <g clip-path="url(#clipper)">
    <g clip-path="url(#clipper)">
    </g>
  </g>
</svg>

with rsvg-view-3 and valigrind produces

==23663== Use of uninitialised value of size 8
==23663==    at 0x6C1FFA1: insert_edge (cairo-boxes-intersect.c:458)
==23663==    by 0x6C20063: sweep_line_insert (cairo-boxes-intersect.c:478)
==23663==    by 0x6C201E1: intersect (cairo-boxes-intersect.c:516)
==23663==    by 0x6C20DE4: _cairo_boxes_intersect (cairo-boxes-intersect.c:685)
==23663==    by 0x6C270BB: _cairo_clip_intersect_boxes (cairo-clip-boxes.c:290)
==23663==    by 0x6C26AAD: _cairo_clip_intersect_rectilinear_path (cairo-clip-boxes.c:145)
==23663==    by 0x6C2500D: _cairo_clip_intersect_path (cairo-clip.c:261)
==23663==    by 0x6C34DE7: _cairo_gstate_clip (cairo-gstate.c:1559)
==23663==    by 0x6C2DE30: _cairo_default_context_clip (cairo-default-context.c:1103)
==23663==    by 0x6C22A38: cairo_clip (cairo.c:2492)
==23663==    by 0x4E5BD6C: rsvg_cairo_clip (rsvg-cairo-clip.c:170)
==23663==    by 0x4E5A348: rsvg_cairo_push_discrete_layer (rsvg-cairo-draw.c:777)

(gdb) where
#0  0x0000000006c1ffa1 in insert_edge (edge=0x7feffe640, pos=0x7feffe3e8) at cairo-boxes-intersect.c:458
#1  0x0000000006c20064 in sweep_line_insert (sweep=0x7feffc3d0, rectangle=0x7feffe640) at cairo-boxes-intersect.c:478
#2  0x0000000006c201e2 in intersect (rectangles=0x7feffe580, num_rectangles=4, out=0x7feffeeb0) at cairo-boxes-intersect.c:516
#3  0x0000000006c20de5 in _cairo_boxes_intersect (a=0x7feffeeb0, b=0x7fefff130, out=0x7feffeeb0) at cairo-boxes-intersect.c:685
#4  0x0000000006c270bc in _cairo_clip_intersect_boxes (clip=0x1246be00, boxes=0x7fefff130) at cairo-clip-boxes.c:290
#5  0x0000000006c26aae in _cairo_clip_intersect_rectilinear_path (clip=0x1246be00, path=0x12465a48, fill_rule=CAIRO_FILL_RULE_WINDING, antialias=CAIRO_ANTIALIAS_DEFAULT) at cairo-clip-boxes.c:145
#6  0x0000000006c2500e in _cairo_clip_intersect_path (clip=0x1246be00, path=0x12465a48, fill_rule=CAIRO_FILL_RULE_WINDING, tolerance=0.10000000000000001, antialias=CAIRO_ANTIALIAS_DEFAULT) at cairo-clip.c:261
#7  0x0000000006c34de8 in _cairo_gstate_clip (gstate=0x1246bc20, path=0x12465a48) at cairo-gstate.c:1559
#8  0x0000000006c2de31 in _cairo_default_context_clip (abstract_cr=0x124656e0) at cairo-default-context.c:1103
#9  0x0000000006c22a39 in cairo_clip (cr=0x124656e0) at cairo.c:2492
#10 0x0000000004e5bd6d in rsvg_cairo_clip (ctx=ctx@entry=0x12465cb0, clip=0x1245e560, bbox=bbox@entry=0x0) at rsvg-cairo-clip.c:170
#11 0x0000000004e59077 in rsvg_cairo_push_early_clips (ctx=ctx@entry=0x12465cb0) at rsvg-cairo-draw.c:718
#12 0x0000000004e5a349 in rsvg_cairo_push_discrete_layer (ctx=0x12465cb0) at rsvg-cairo-draw.c:777
#13 0x0000000004e4ef8b in _rsvg_node_draw_children (self=0x12463600, ctx=0x12465cb0, dominate=0) at rsvg-structure.c:83
#14 0x0000000004e4ef43 in rsvg_node_draw (self=0x12463600, ctx=0x12465cb0, dominate=<optimized out>) at rsvg-structure.c:69
#15 0x0000000004e4efc3 in _rsvg_node_draw_children (self=0x124624a0, ctx=0x12465cb0, dominate=0) at rsvg-structure.c:87
#16 0x0000000004e4ef43 in rsvg_node_draw (self=0x124624a0, ctx=0x12465cb0, dominate=<optimized out>) at rsvg-structure.c:69
#17 0x0000000004e4f343 in rsvg_node_svg_draw (self=0x1245c4d0, ctx=0x12465cb0, dominate=<optimized out>) at rsvg-structure.c:323
#18 0x0000000004e4ef43 in rsvg_node_draw (self=0x1245c4d0, ctx=0x12465cb0, dominate=<optimized out>) at rsvg-structure.c:69
#19 0x0000000004e574e3 in rsvg_handle_get_dimensions_sub (handle=0x12455230, dimension_data=0x7fefff838, id=<optimized out>, id@entry=0x0) at rsvg-base.c:1424
#20 0x0000000004e57779 in rsvg_handle_get_dimensions (handle=0x12455230, dimension_data=dimension_data@entry=0x7fefff838) at rsvg-base.c:1337
#21 0x0000000000403cc7 in main (argc=1, argv=0x7fefffc48) at test-display.c:773
(gdb) l
453                     })
454                 } while (TRUE);
455             }
456         }
457
458         pos->prev->next = edge;
459         edge->prev = pos->prev;
460         edge->next = pos;
461         pos->prev = edge;
462     }
(gdb) p pos->prev
$1 = (edge_t *) 0xe
(gdb) p *pos
$2 = {next = 0x7feffe668, prev = 0xe, right = 0x0, x = -2147483648, top = 0, a_or_b = 306519600, dir = 0}

Please tell me if I should file this in a new bug, or in one of the old ones.
Comment 9 Chris Wilson 2015-04-23 06:58:32 UTC
(In reply to Federico Mena-Quintero from comment #8)
> (In reply to Chris Wilson from comment #7)
> > Created attachment 115240 [details] [review] [review] [review]
> > Preliminary stroke validation
> 
> This is really nice!  It fixes the problem very cleanly - valgrind shows no
> problems with the fuzzed file.
> 
> (And thanks for making me aware of CAIRO_STATUS_INVALID_SIZE; hopefully
> we'll have a lot more of it in the future :)

If we start doing this, we should pick a new error status stg CAIRO_STATUS_INVALID_RASTER_VALUE or perhaps CAIRO_STATUS_INVALID_FIXEDPOINT_LINE_WIDTH or
CAIRO_STATUS_INVALID_RASTER_STROKE?
 
> Chris, since you just put your foot into the rabbit hole :)  May I interest
> you in another fixed-point overflow thing?  This goes back to the old bugs
> #20091 and #39096.  Using this fuzzed svg
> 
> <svg>
>   <defs>
>     <clipPath id="clipper">
>       <rect y="19" width="2" height="2" />
>       <rect width="18446744073709551616" height="29" />
>     </clipPath>
>   </defs>
>   <g clip-path="url(#clipper)">
>     <g clip-path="url(#clipper)">
>     </g>
>   </g>
> </svg>
> 
> with rsvg-view-3 and valigrind produces...

The error is in the stage before not successfully generating a watertight clipped polygon. It's one of those impossible conditions since it is only meant to output pairs of edges, but the error you see later on is when you find an edge with no pair.
Comment 10 Bryce Harrington 2015-06-16 18:52:45 UTC
Chris' patch looks good to me.

It's been a couple months with no further discussion, and sounds like this patch solves the problem.  Should we land it or is there any further details to be sorted out?  E.g. adding a new error type for this (or is that suggested as followup work?
Comment 11 Bryce Harrington 2015-07-27 18:16:59 UTC
I'm wrapping up the current stable release, and it would be great to get confirmation that this patch can be landed now.

If not, then maybe what I'll do is land it as soon as the next development cycle opens, so it gets maximum testing before release.
Comment 12 Bryce Harrington 2016-10-19 00:52:30 UTC
Unfortunately the patch causes a number of test failures:

==> results_master.txt <==
#######
# Tests run:        531
# Passed:           492
# Failed:           26
# Expected Failed:  13
# Error:            0
# Crashed:          0
# Untested:         0
# Total:            531
#######

==> results.txt <==
#######
# Tests run:        531
# Passed:           341
# Failed:           165
# Expected Failed:  13
# Error:            2
# Crashed:          10
# Untested:         0
# Total:            531
#######

PASS -> FAIL # a1-clip-stroke.image.argb32
PASS -> FAIL # a1-line-width.image.argb32
PASS -> FAIL # a1-rectilinear-grid.image.argb32
PASS -> FAIL # a8-clear.image.argb32
PASS -> FAIL # aliasing.image.argb32
PASS -> ERROR # api-special-cases.image.argb32
PASS -> FAIL # arc-looping-dash.image.argb32
PASS -> FAIL # big-line.image.argb32
PASS -> FAIL # bug-51910.image.argb32
PASS -> FAIL # bug-84115.image.argb32
PASS -> FAIL # bug-extents.image.argb32
PASS -> FAIL # bug-spline.image.argb32
PASS -> FAIL # caps-05.image.argb32
PASS -> FAIL # caps-1.image.argb32
PASS -> FAIL # caps-2.image.argb32
PASS -> FAIL # caps-joins-05.image.argb32
PASS -> FAIL # caps-joins-1.image.argb32
PASS -> FAIL # caps-joins-2.image.argb32
PASS -> FAIL # caps-joins-alpha.image.argb32
PASS -> FAIL # caps-joins-curve.image.argb32
PASS -> FAIL # caps-joins.image.argb32
PASS -> FAIL # caps.image.argb32
PASS -> FAIL # caps-sub-paths.image.argb32
PASS -> FAIL # caps-tails-curve.image.argb32
PASS -> CRASHED # clear-source.image.argb32
PASS -> FAIL # clip-disjoint.image.argb32
PASS -> FAIL # clip-shape.image.argb32
PASS -> FAIL # clip-stroke.image.argb32
PASS -> FAIL # clip-stroke-unbounded.image.argb32
PASS -> FAIL # close-path-current-point.image.argb32
PASS -> FAIL # curve-to-as-line-to.image.argb32
PASS -> FAIL # dash-caps-joins.image.argb32
PASS -> FAIL # dash-curve.image.argb32
PASS -> FAIL # dash-infinite-loop.image.argb32
PASS -> FAIL # dash-no-dash.image.argb32
PASS -> FAIL # dash-offset.image.argb32
PASS -> FAIL # dash-offset-negative.image.argb32
PASS -> FAIL # dash-scale.image.argb32
PASS -> FAIL # dash-state.image.argb32
PASS -> FAIL # dash-zero-length.image.argb32
PASS -> FAIL # degenerate-arc.image.argb32
PASS -> FAIL # degenerate-curve-to.image.argb32
PASS -> FAIL # degenerate-dash.image.argb32
PASS -> FAIL # degenerate-path.image.argb32
PASS -> FAIL # degenerate-pen.image.argb32
PASS -> FAIL # degenerate-rel-curve-to.image.argb32
PASS -> FAIL # degenerate-solid-dash.image.argb32
PASS -> FAIL # drunkard-tails.image.argb32
PASS -> FAIL # fill-and-stroke-alpha-add.image.argb32
PASS -> FAIL # fill-and-stroke-alpha.image.argb32
PASS -> FAIL # fill-and-stroke.image.argb32
PASS -> FAIL # filter-nearest-offset.image.argb32
PASS -> FAIL # font-matrix-translation.image.argb32
PASS -> FAIL # ft-text-vertical-layout-type1.image.argb32
PASS -> FAIL # ft-text-vertical-layout-type3.image.argb32
PASS -> FAIL # get-path-extents.image.argb32
PASS -> FAIL # halo.image.argb32
PASS -> FAIL # halo-transform.image.argb32
PASS -> FAIL # image-bug-710072-aligned.image.argb32
PASS -> FAIL # image-bug-710072-unaligned.image.argb32
PASS -> FAIL # implicit-close.image.argb32
PASS -> FAIL # infinite-join.image.argb32
PASS -> FAIL # joins.image.argb32
PASS -> FAIL # joins-loop.image.argb32
PASS -> FAIL # joins-retrace.image.argb32
PASS -> FAIL # joins-star.image.argb32
PASS -> CRASHED # large-twin-antialias-mixed.image.argb32
PASS -> FAIL # leaky-dashed-rectangle.image.argb32
PASS -> FAIL # leaky-dashed-stroke.image.argb32
PASS -> FAIL # leaky-dash.image.argb32
PASS -> FAIL # line-width-large-overlap-dashed.image.argb32
PASS -> FAIL # line-width-large-overlap-flipped.image.argb32
PASS -> FAIL # line-width-large-overlap-flopped.image.argb32
PASS -> FAIL # line-width-large-overlap.image.argb32
PASS -> FAIL # line-width-large-overlap-offset.image.argb32
PASS -> FAIL # line-width-large-overlap-rotated.image.argb32
PASS -> FAIL # line-width.image.argb32
PASS -> FAIL # line-width-overlap-dashed.image.argb32
PASS -> FAIL # line-width-overlap-flipped.image.argb32
PASS -> FAIL # line-width-overlap-flopped.image.argb32
PASS -> FAIL # line-width-overlap.image.argb32
PASS -> FAIL # line-width-overlap-offset.image.argb32
PASS -> FAIL # line-width-overlap-rotated.image.argb32
PASS -> FAIL # line-width-scale.image.argb32
PASS -> FAIL # line-width-tolerance.image.argb32
PASS -> FAIL # long-dashed-lines.image.argb32
PASS -> FAIL # miter-precision.image.argb32
PASS -> FAIL # new-sub-path.image.argb32
PASS -> FAIL # outline-tolerance.image.argb32
PASS -> FAIL # overlapping-dash-caps.image.argb32
PASS -> FAIL # path-stroke-twice.image.argb32
PASS -> FAIL # pixman-rotate.image.argb32
PASS -> FAIL # push-group-color.image.argb32
PASS -> FAIL # push-group.image.argb32
PASS -> FAIL # random-clip.image.argb32
PASS -> FAIL # random-intersections-curves-eo.image.argb32
PASS -> FAIL # random-intersections-curves-nz.image.argb32
PASS -> FAIL # random-intersections-eo.image.argb32
PASS -> FAIL # random-intersections-nonzero.image.argb32
PASS -> FAIL # record1414x-self-intersecting.image.argb32
PASS -> FAIL # record2x-self-intersecting.image.argb32
PASS -> FAIL # record90-self-intersecting.image.argb32
PASS -> FAIL # recordflip-self-intersecting.image.argb32
PASS -> FAIL # recordflip-whole-self-intersecting.image.argb32
PASS -> FAIL # recording-surface-extend-none.image.argb32
PASS -> FAIL # recording-surface-extend-reflect.image.argb32
PASS -> FAIL # recording-surface-extend-repeat.image.argb32
PASS -> FAIL # recording-surface-over.image.argb32
PASS -> FAIL # recording-surface-source.image.argb32
PASS -> FAIL # record-self-intersecting.image.argb32
PASS -> FAIL # rectilinear-dash.image.argb32
PASS -> FAIL # rectilinear-dash-scale.image.argb32
PASS -> FAIL # rectilinear-dash-scale-unaligned.image.argb32
PASS -> FAIL # rectilinear-grid.image.argb32
PASS -> FAIL # rectilinear-miter-limit.image.argb32
PASS -> FAIL # rectilinear-stroke.image.argb32
PASS -> FAIL # reflected-stroke.image.argb32
PASS -> FAIL # rel-path.image.argb32
PASS -> FAIL # rotated-clip.image.argb32
PASS -> FAIL # rotate-stroke-box.image.argb32
PASS -> FAIL # rounded-rectangle-stroke.image.argb32
PASS -> FAIL # scale-offset-image.image.argb32
PASS -> FAIL # scale-offset-similar.image.argb32
PASS -> FAIL # shape-general-convex.image.argb32
PASS -> FAIL # shape-sierpinski.image.argb32
PASS -> FAIL # skew-extreme.image.argb32
FAIL -> ERROR # smask.image.argb32
PASS -> FAIL # smask-stroke.image.argb32
PASS -> FAIL # solid-pattern-cache-stress.image.argb32
PASS -> FAIL # spline-decomposition.image.argb32
PASS -> FAIL # stroke-clipped.image.argb32
PASS -> FAIL # stroke-ctm-caps.image.argb32
PASS -> FAIL # stroke-image.image.argb32
PASS -> FAIL # stroke-open-box.image.argb32
PASS -> FAIL # stroke-pattern.image.argb32
PASS -> CRASHED # subsurface.image.argb32
PASS -> CRASHED # subsurface-scale.image.argb32
PASS -> FAIL # text-glyph-range.image.argb32
PASS -> FAIL # text-rotate.image.argb32
PASS -> FAIL # transforms.image.argb32
PASS -> CRASHED # twin-antialias-gray.image.argb32
PASS -> CRASHED # twin-antialias-mixed.image.argb32
PASS -> CRASHED # twin-antialias-none.image.argb32
PASS -> CRASHED # twin-antialias-subpixel.image.argb32
PASS -> CRASHED # twin.image.argb32
PASS -> FAIL # unantialiased-shapes.image.argb32
PASS -> FAIL # unclosed-strokes.image.argb32
PASS -> CRASHED # user-font.image.argb32
PASS -> FAIL # user-font-mask.image.argb32
PASS -> FAIL # world-map.image.argb32
PASS -> FAIL # world-map-stroke.image.argb32
PASS -> FAIL # xlib-expose-event.image.argb32

This error message is in a lot of the results files:

Error: Failed to extract image: invalid value (typically too big) for the size of the input (surface, pattern, etc.)

In a few cases, output images are generated for the failures, which can be viewed in the HTML results page, and just eyeballing them it looks like lines aren't getting stroked that should be getting stroked.

I couldn't say whether the fault is with the patch or the tests, but either way the patch looks like it needs a bit more work (or needs to include updates to test cases) before its landable.
Comment 13 GitLab Migration User 2018-08-25 13:33:01 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/cairo/cairo/issues/62.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.