Bug 31897

Summary: _composite_glyphs: Assertion `! (((this_x+4096) | (this_y+4096)) & ~0x3fffu)' failed.
Product: cairo Reporter: ojab <ojab>
Component: xcb backendAssignee: Carl Worth <cworth>
Status: RESOLVED FIXED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium CC: freedesktop, psychon
Version: 1.10.1   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: gdb bt full
Test (ugly) case that (hopefuly) does the same thing wireshark does
Patch that apparently fixes this bug

Description ojab 2010-11-24 06:58:30 UTC
Getting an assertion while starting wireshark's VoIP calls player, reproducible with cairo-git-493aaf0 & cairo-1.10.0.
Comment 1 ojab 2010-11-24 06:59:30 UTC
Created attachment 40548 [details]
gdb bt full
Comment 2 Uli Schlachter 2010-11-24 08:31:44 UTC
My local git clone doesn't know a commit with hash 493aaf0, did I miss something?

Also, which version of wireshark are you using? I can't reproduce this with debian's 1.2.11-3. Does this require some VoIP data to trigger the assert or does it also trigger with an empty list of VoIP calls?
Comment 3 ojab 2010-11-24 08:56:05 UTC
cairo git master branch from fdo:

commit 493aaf0f15bfedc88371ffab07d862a400b0da38
Author: Andrea Canciani <>
Date:   Wed Nov 24 12:08:03 2010 +0100

    array: Cleanup types

compiled with --enable-xlib-xcb --enable-xcb --enable-gl --enable-qt

wireshark trunk r35019, libxcb-1.7, xcb-proto-1.6.
Assertion can be triggered with attached pcap trace, you should go to Telephony -> VoIP Calls -> Select only call -> Player -> Decode -> Crash
Comment 4 ojab 2010-11-24 08:59:26 UTC
Unfortunately trace is too big to be attached (1,5Mb compressed), you can download it from http://ojab.ru/tst.cap.bz2
Comment 5 Uli Schlachter 2010-11-24 10:22:34 UTC
Created attachment 40551 [details]
Test (ugly) case that (hopefuly) does the same thing wireshark does

My cairo clone was outdated, sorry for that.
I can reproduce this problem with the provided pcap trace, thanks a lot.

Wireshark allocates a 15124x100 surface which is large enough to hit this problem and then draws text to it.
The Xlib backend handles this case by doing a fallback instead of assert().

Just removing the assert() doesn't seem to cause any integer overflows (xtrace output looks good), but I bet there are cases out there which manage to hit the overflow.
Comment 6 Uli Schlachter 2010-12-19 08:46:25 UTC
Created attachment 41258 [details] [review]
Patch that apparently fixes this bug

Attached is a patch by ranma42 that seems to fix this bug. I ported the same change to xlib backend, which might make sense there, too.

All coordinates on a drawable should be addressable through the X11 protocol. So this just starts a new glyph chunk when the difference between glyph coordinates becomes too large.
Comment 7 Behdad Esfahbod 2010-12-21 11:47:55 UTC
Your patch is on the right track, but not complete.  It doesn't handle the case of a glyph x,y outside of int16.  Let me fix the Xlib backend and let you port it to xcb.
Comment 8 Behdad Esfahbod 2010-12-21 12:15:59 UTC
After studying the code again, and studying xrender/Glyph.c, I think the current code in xlib is as good as any.
Comment 9 Andrea Canciani 2011-01-02 10:39:36 UTC
I tried to improve the patch:
http://cgit.freedesktop.org/~ranma42/cairo/log/?h=wip/for-psychon

Did I forgot anything else? Should we port back to xlib?
Comment 10 Andrea Canciani 2011-01-06 05:05:51 UTC
An improved patchset has been pushed to master:

commit 10bae9d9ce5ece5bc5b4a929e791d9906a6b24b5
Author: Andrea Canciani <ranma42@gmail.com>
Date:   Wed Dec 22 00:24:59 2010 +0100

    xcb: Stricter glyph validation
    
    To ensure that we can correctly issue the glyph operation, glyph size
    must fit in an XCB request and its position must be within the
    representable range (16-bit offset).

commit 588dead005d69c022245ff017f53ff403b50e9db
Author: Andrea Canciani <ranma42@gmail.com>
Date:   Wed Dec 22 11:30:45 2010 +0100

    xcb: Handle a wider range of glyph positions
    
    _can_composite_glyphs() checks that the position of each glyph can be
    represented as a 16-bit offset from the destination origin.
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=31897
Comment 11 Behdad Esfahbod 2011-01-06 10:49:18 UTC
Please push to xlib too.  I'll review after to see if all the details are correct.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.