diff --git a/test/bug-crash-tessellate.c b/test/bug-crash-tessellate.c new file mode 100644 index 000000000..5c68de899 --- /dev/null +++ b/test/bug-crash-tessellate.c @@ -0,0 +1,104 @@ +/* + * Copyright © 2025 Uli Schlachter + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Author: Uli Schlachter + */ + +#include "cairo-test.h" + +static cairo_test_status_t +draw_y (cairo_t *cr, int width, int height) +{ + // the minimum value that cairo_fixed_t can represent + // (because it uses a 24.8 fixed point format) + double fixed_min = INT32_MIN / (double) (1 << 8); + + // Fill the output with black so that CONTENT_COLOR and CONTENT_COLOR_ALPHA + // can use the same reference image. + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_paint (cr); + + // Work around the clamping done by commit 47a21c6e30eef91db503a5a183d5c8cf558aaa56 + cairo_set_line_width(cr, 1.0 / (double) (1 << 16)); + + // Some identical rectangles with their lower edge at fixed_min + cairo_rectangle (cr, 0, fixed_min, 10, 10); + cairo_rectangle (cr, 0, fixed_min, 10, 10); + cairo_rectangle (cr, 0, fixed_min, 10, -10); + cairo_rectangle (cr, 0, fixed_min, 10, -10); + + cairo_clip (cr); + + return CAIRO_TEST_SUCCESS; +} + +static cairo_test_status_t +draw_pdf (cairo_t *cr, int width, int height) +{ + // This is a reduction from some drawing commands found in a PDF + cairo_matrix_t m1 = {1, 0, 0, -1, 0, 792}; + cairo_matrix_t m2 = {8262, 0, 0, 0.148262, 0, 0}; + + // Fill the output with black so that CONTENT_COLOR and CONTENT_COLOR_ALPHA + // can use the same reference image. + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_paint (cr); + + cairo_transform(cr, &m1); + cairo_transform(cr, &m2); + cairo_set_line_width(cr, 0.0000145243); + + cairo_new_path(cr); + + cairo_move_to(cr, 801.285, 801.285); + cairo_line_to(cr, 3205.145, 801.285); + cairo_line_to(cr, 3205.145, 1602.57); + cairo_line_to(cr, 801.285, 1602.57); + cairo_line_to(cr, 801.285, 801.285); + cairo_close_path(cr); + + cairo_move_to(cr, 801.285, 2403.86); + cairo_line_to(cr, 3205.145, 2403.86); + cairo_line_to(cr, 3205.145, 3205.145); + cairo_line_to(cr, 801.285, 3205.145); + cairo_line_to(cr, 801.285, 2403.86); + cairo_close_path(cr); + + cairo_clip(cr); + + return CAIRO_TEST_SUCCESS; +} + +CAIRO_TEST (bug_crash_tessellate_y, + "Trigger a crash in _cairo_bentley_ottmann_tessellate_rectangular with overlapping rectangles near the minimum possible y coordinate", + NULL, /* keywords */ + NULL, /* requirements */ + 1, 1, + NULL, draw_y) + +CAIRO_TEST (bug_crash_tessellate_pdf, + "Trigger a crash in _cairo_bentley_ottmann_tessellate_rectangular; reduced from a PDF", + NULL, /* keywords */ + NULL, /* requirements */ + 1, 1, + NULL, draw_pdf) diff --git a/test/meson.build b/test/meson.build index 786ac2a84..015529e36 100644 --- a/test/meson.build +++ b/test/meson.build @@ -23,6 +23,7 @@ test_sources = [ 'big-little-triangle.c', 'bug-spline.c', 'big-trap.c', + 'bug-crash-tessellate.c', 'bilevel-image.c', 'bug-277.c', 'bug-361.c', diff --git a/test/reference/bug-crash-tessellate-pdf.ref.png b/test/reference/bug-crash-tessellate-pdf.ref.png new file mode 100644 index 000000000..7d5589c1d Binary files /dev/null and b/test/reference/bug-crash-tessellate-pdf.ref.png differ diff --git a/test/reference/bug-crash-tessellate-y.ref.png b/test/reference/bug-crash-tessellate-y.ref.png new file mode 100644 index 000000000..7d5589c1d Binary files /dev/null and b/test/reference/bug-crash-tessellate-y.ref.png differ