steal boxes: Fix an invalif free() exposed by cb871c6c
Commits cb871c6c made the function _cairo_clip_reduce_to_boxes() actually do something instead of being a no-op. This exposed a latent bug in cairo that was so far just not hit due to luck. The function _cairo_clip_steal_boxes() removes the boxes from a clip and gives them to a cairo_boxes_t. _cairo_clip_unsteal_boxes() undoes this operation. For efficiency reasons, cairo_clip_t contains an embedded cairo_box_t that is used when the clip has only one box to avoid a memory allocation. Thus, _cairo_clip_unsteal_boxes() must be called on the same clip that was given to _cairo_clip_steal_boxes(), or otherwise a clip could end up to the embedded box of another instance of cairo_clip_t. This is exactly what was happening here. For example, cairo-xcb can replace extents->clip with another clip via the call chain _cairo_xcb_render_compositor_paint() (which is where boxes are stolen) -> _clip_and_composite_boxes() -> trim_extents_to_traps() -> _cairo_composi...
Showing with 15 additions and 2 deletions