[cairo] crash in _fill_xrgb32_lerp_opaque_spans

Bryce Harrington bryce at osg.samsung.com
Wed Dec 3 20:03:28 PST 2014


Thanks, I'll post the fix in patch form, for review.  Your fix looks
good but it might suggest the existance of a more fundamental error.

Bryce

On Sun, Nov 30, 2014 at 11:16:39PM +0300, Ilya Sakhnenko wrote:
> Hello,
> 
> Please excuse me for creating a confusion. Here is the original source code
> with the comments regarding the crash.
> cairo-image-compositor.c
> 
> static cairo_status_t
> _fill_xrgb32_lerp_opaque_spans (void *abstract_renderer, int y, int h,
>                 const cairo_half_open_span_t *spans, unsigned num_spans)
> {
>     cairo_image_span_renderer_t *r = abstract_renderer;
> 
>     if (num_spans == 0)
>     return CAIRO_STATUS_SUCCESS;
> 
>     if (likely(h == 1)) {
>     do {
>         uint8_t a = spans[0].coverage;
>         if (a) {
>         int len = spans[1].x - spans[0].x; // = -1 causing a crash below
>         uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y +
> spans[0].x*4);
>         if (a == 0xff) {
>             if (len > 31) {
>             pixman_fill ((uint32_t *)r->u.fill.data, r->u.fill.stride /
> sizeof(uint32_t), 32,
>                      spans[0].x, y, len, 1, r->u.fill.pixel);
>             } else {
>             uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y +
> spans[0].x*4);
>             while (len--)
>                 *d++ = r->u.fill.pixel;
>             }
>         } else while (len--) {
>             *d = lerp8x4 (r->u.fill.pixel, a, *d); // the crash happens
> here, len < -20000
>             d++;
>         }
>         }
>         spans++;
>     } while (--num_spans > 1);
>     } else {
>     do {
> 
> 
> With best regards,
> Ilya
> 
> On 27 November 2014 at 01:04, Ilya Sakhnenko <ilia.softway at gmail.com> wrote:
> 
> > Hello,
> >
> > First of all, million thanks for this beautiful library!
> > I have encountered a crash in _fill_xrgb32_lerp_opaque_spans (cairo
> > 1.14.0, pixman 0.32.6):
> >
> > I had to replace if (len--) to if (len-- > 0) to let our program run.
> >
> > static cairo_status_t
> > _fill_xrgb32_lerp_opaque_spans (void *abstract_renderer, int y, int h,
> >                 const cairo_half_open_span_t *spans, unsigned num_spans)
> > {
> >     cairo_image_span_renderer_t *r = abstract_renderer;
> >
> >     if (num_spans == 0)
> >     return CAIRO_STATUS_SUCCESS;
> >
> >     if (likely(h == 1)) {
> >     do {
> >         uint8_t a = spans[0].coverage;
> >         if (a) {
> >         int len = spans[1].x - spans[0].x; // = -1 causing a crash
> >         uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y +
> > spans[0].x*4);
> >         if (a == 0xff) {
> >             if (len > 31) {
> >             pixman_fill ((uint32_t *)r->u.fill.data, r->u.fill.stride /
> > sizeof(uint32_t), 32,
> >                      spans[0].x, y, len, 1, r->u.fill.pixel);
> >             } else {
> >             uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y
> > + spans[0].x*4);
> >             while (len-- > 0)
> >                 *d++ = r->u.fill.pixel;
> >             }
> >         } else while (len-- > 0) { // crash len being negative (was -1 at
> > the line 2238: int len = spans[1].x - spans[0].x)
> >             *d = lerp8x4 (r->u.fill.pixel, a, *d);
> >             d++;
> >         }
> >         }
> >         spans++;
> > ....
> >
> > With best regards,
> > Ilya
> >
> >

> -- 
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo



More information about the cairo mailing list