Crash program with cairo_recording_surface_create and with big rectangle size
Uli Schlachter
psychon at znc.in
Sat Mar 16 18:08:27 UTC 2024
Hi,
Am 15.03.24 um 13:28 schrieb Kęstutis:
> What is the maximum width and height of a rectangle that I can use with
> the recording surface?
From the top of my head: I don't know about any limits.
> When I attempted to use a rectangle with dimensions of 39000x57400, the
> program crashed with a General Protection Fault (GPF) due to an endless
> recursion occurring in the function |bbtree_add| within the module
> |cairo-recording-surface.c|.
>
> I have attached an example of the program.
>
> Could someone please provide assistance with this situation?
Sure. My first thought is: Here is the link to the issue tracker [1].
[1]: https://gitlab.freedesktop.org/freedesktop/freedesktop/-/issues/new
> Thank you for any insights and best regards.
I have no clue about this code, so I did some printf-debugging. The
patch is attached. With this patch, your program produces repeated
output like the following (the pointers of course differ, but the
coordinates stay the same in the many calls):
bbtree_left_or_right(bbt{left=(nil), right=(nil)}, box=(8352000,
14707200) to (8606720, 14745088))
left=0
right=0
left_or_right returning 1
bbtree_left_or_right(bbt{left=0x564b424aec00, right=(nil)}, box=(0, 0)
to (9984000, 14694400))
bbt->left_extents=(8352000, 14707200) to (8606720, 14745088)
Union=(0, 0) to (9984000, 14745088)
left=-2048792556
right=0
left_or_right returning 1
The value for "left" in the second call obviously looks like an integer
overflow. Also, bbt->left_extents look invalid there. If I understand
this code correctly, cairo_box_t is a rectangle where p1 is the upper
left corner and p2 is the lower right corner.
The coordinates in a cairo_box_t are saved as a cairo_fixed_t, which is
a fixed point number. 24 bits are used for the integer part and 8 bits
for the fractional part. So, just from this, I guess that the possible
value range is between -2^23 and 2^23 - 1. Just from the numbers, your
program stays within these limits. However, I don't know what happens
with the text with this large font size or the transformation matrix.
Perhaps some coordinate ends up being larger than this and the resulting
integer overflow breaks everything?
Going back to the output above...
bbt->left_extents=(8352000, 14707200) to (8606720, 14745088)
Union=(0, 0) to (9984000, 14745088)
...decoding (= divide by 2^8) the fixed point numbers results in:
bbt->left_extents=(32625.00, 57450.00) to (33620.00, 57598.00)
Union=(0, 0) to (39000.00, 57598.00)
Hm....
The code in bbtree_left_or_right() computes left as (width-of-union *
height-of-union) - (width-of-extends) * (height-of-extends). So... if I
understand this correctly, this computes the difference of the areas of
the two boxes and because these boxes are so huge, there is an overflow?
(The code also uses _cairo_fixed_integer_part() to only look at full
pixels within? Or perhaps this is supposed to protect against overflows
by making the numbers slightly smaller? I don't know.)
Changing the type of "left" and "right" to "int64_t" and adding a cast
to int64_t to the multiplication changes the complete output of the test
case to:
bbtree_left_or_right(bbt{left=(nil), right=(nil)}, box=(8352000,
14707200) to (8606720, 14745088))
left=0
right=0
left_or_right returning 1
bbtree_left_or_right(bbt{left=0x55e6572fc570, right=(nil)}, box=(0, 0)
to (9984000, 14694400))
bbt->left_extents=(8352000, 14707200) to (8606720, 14745088)
Union=(0, 0) to (9984000, 14745088)
left=2246174740
right=0
left_or_right returning 0
bbtree_left_or_right(bbt{left=(nil), right=(nil)}, box=(102400, 57344)
to (430336, 100352))
left=0
right=0
left_or_right returning 1
This change is also attached as a patch. Perhaps that can be included in
your bug report.
Cheers,
Uli
--
Do you remember what we used to say back then?
One impossible thing at a time.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: printf.patch
Type: text/x-diff
Size: 2177 bytes
Desc: not available
URL: <https://lists.cairographics.org/archives/cairo/attachments/20240316/613aab5d/attachment.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: possible_fix.patch
Type: text/x-diff
Size: 1075 bytes
Desc: not available
URL: <https://lists.cairographics.org/archives/cairo/attachments/20240316/613aab5d/attachment-0001.patch>
More information about the cairo
mailing list