Memory leak when "no-op drawing" with an operator not bounded by the mask
Heiko's WIP fuzzer found a memory leak: !154 (comment 884082)
Reduced, self-contained, compilable reproducer:
#include <cairo.h>
#include <cairo-pdf.h>
int main()
{
cairo_surface_t *surface = cairo_pdf_surface_create("/dev/null", -1, -1);
cairo_t *cr = cairo_create(surface);
cairo_set_operator(cr, CAIRO_OPERATOR_DEST_ATOP);
cairo_paint_with_alpha(cr, 0.5);
cairo_destroy(cr);
cairo_surface_destroy(surface);
return 0;
}
It is important that the PDF surface has size -1, -1. The operator needs to be something that produces FALSE
from _cairo_operator_bounded_by_mask
.
The code produces CAIRO_INT_STATUS_NOTHING_TO_DO
here and afterwards we just return
, return
. However, there was already some memory allocated to represent... something. https://gitlab.freedesktop.org/cairo/cairo/-/blob/7de7d57592370fbf625741526c689f747db15174/src/cairo-composite-rectangles.c#L167
The code starting from line 161 in that file is only reached for operators that are not bounded by the mask, which is the case only for OUT, IN, DEST_IN, and DEST_ATOP. I guess this is why this issue was not found before.
Valgrind says:
==22341== 72 bytes in 1 blocks are definitely lost in loss record 1 of 8
==22341== at 0x483877F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==22341== by 0x4870846: _cairo_clip_create (cairo-clip.c:111)
==22341== by 0x486BFE9: _cairo_clip_intersect_rectangle_box (cairo-clip-boxes.c:159)
==22341== by 0x486C865: _cairo_clip_intersect_rectangle (cairo-clip-boxes.c:373)
==22341== by 0x486CC83: _cairo_clip_reduce_to_rectangle (cairo-clip-boxes.c:575)
==22341== by 0x486CD04: _cairo_clip_reduce_for_composite (cairo-clip-boxes.c:591)
==22341== by 0x4872C11: _cairo_composite_rectangles_intersect (cairo-composite-rectangles.c:161)
==22341== by 0x48732E7: _cairo_composite_rectangles_init_for_mask (cairo-composite-rectangles.c:336)
==22341== by 0x48C33C1: _cairo_recording_surface_mask (cairo-recording-surface.c:781)
==22341== by 0x48E31A0: _cairo_surface_mask (cairo-surface.c:2251)
==22341== by 0x489CE7E: _cairo_paginated_surface_mask (cairo-paginated-surface.c:650)
==22341== by 0x48E31A0: _cairo_surface_mask (cairo-surface.c:2251)