[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