Merge branch 'bentley-ottman-crash' into 'master'

Fix / work around two NULL pointer dereferences in _cairo_bentley_ottmann_tessellate_rectangular

See merge request cairo/cairo!632
This commit is contained in:
Uli Schlachter 2026-03-04 18:03:43 +00:00
commit b762f51d31
5 changed files with 109 additions and 0 deletions

View file

@ -847,12 +847,16 @@ _cairo_bentley_ottmann_tessellate_boxes (const cairo_boxes_t *in,
rectangles[j].left.x = box[i].p2.x;
rectangles[j].left.dir = -1;
}
if (unlikely (rectangles[j].left.x == INT32_MAX)) rectangles[j].left.x = INT32_MAX-1;
if (unlikely (rectangles[j].right.x == INT32_MAX)) rectangles[j].right.x = INT32_MAX-1;
rectangles[j].left.right = NULL;
rectangles[j].right.right = NULL;
rectangles[j].top = box[i].p1.y;
rectangles[j].bottom = box[i].p2.y;
if (unlikely (rectangles[j].top == INT32_MIN)) rectangles[j].top = INT32_MIN+1;
if (unlikely (rectangles[j].bottom == INT32_MIN)) rectangles[j].bottom = INT32_MIN+1;
if (rectangles_chain) {
h = _cairo_fixed_integer_floor (box[i].p1.y) - y_min;

104
test/bug-crash-tessellate.c Normal file
View file

@ -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 <psychon@znc.in>
*/
#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)

View file

@ -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',

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B