tetromino 15/03/05 18:22:53 Added: cairo-1.14.0-xcb-0-sized-glyph.patch cairo-1.14.0-xlib-0-sized-glyph.patch cairo-1.14.0-tor-scan-converter-do_fullrow-intersection.patch cairo-1.14.0-CFF-unaligned-access.patch cairo-1.14.0-image-negative-span-length.patch Log: Add upstream patches to fix several crashes. Should fix bug #541326 (heap corruption in darktable and evince), thanks to sergeev917 and Andrey Volkov. (Portage version: 2.2.18/cvs/Linux x86_64, signed Manifest commit with key 0x18E5B6F2D8D5EC8D)
Revision Changes Path 1.1 x11-libs/cairo/files/cairo-1.14.0-xcb-0-sized-glyph.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-xcb-0-sized-glyph.patch?rev=1.1&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-xcb-0-sized-glyph.patch?rev=1.1&content-type=text/plain Index: cairo-1.14.0-xcb-0-sized-glyph.patch =================================================================== >From a03f2ff72054c9530f98738aac729354a3f56102 Mon Sep 17 00:00:00 2001 From: Adam Jackson <a...@redhat.com> Date: Fri, 31 Oct 2014 13:21:15 -0400 Subject: [PATCH 2/2] xcb: Don't crash when swapping a 0-sized glyph malloc(0) needn't return NULL, and on glibc, doesn't. Then we encounter a loop of the form do { ... } while (--c), which doesn't do quite what you were hoping for when c is initially 0. Since there's nothing to swap in this case, just bomb out. Signed-off-by: Adam Jackson <a...@redhat.com> --- src/cairo-xcb-surface-render.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c index 21a89cc..1a086a2 100644 --- a/src/cairo-xcb-surface-render.c +++ b/src/cairo-xcb-surface-render.c @@ -4467,6 +4467,9 @@ _cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection, const uint8_t *d; uint8_t *new, *n; + if (c == 0) + break; + new = malloc (c); if (unlikely (new == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -4495,6 +4498,9 @@ _cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection, const uint32_t *d; uint32_t *new, *n; + if (c == 0) + break; + new = malloc (4 * c); if (unlikely (new == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); -- 2.3.1 1.1 x11-libs/cairo/files/cairo-1.14.0-xlib-0-sized-glyph.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-xlib-0-sized-glyph.patch?rev=1.1&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-xlib-0-sized-glyph.patch?rev=1.1&content-type=text/plain Index: cairo-1.14.0-xlib-0-sized-glyph.patch =================================================================== >From 3cf862f6d973755cd9824c2224fbe0a623c47ff1 Mon Sep 17 00:00:00 2001 From: Adam Jackson <a...@redhat.com> Date: Fri, 31 Oct 2014 13:21:14 -0400 Subject: [PATCH 1/2] xlib: Don't crash when swapping a 0-sized glyph malloc(0) needn't return NULL, and on glibc, doesn't. Then we encounter a loop of the form do { ... } while (--c), which doesn't do quite what you were hoping for when c is initially 0. Since there's nothing to swap in this case, just bomb out. Signed-off-by: Adam Jackson <a...@redhat.com> --- src/cairo-xlib-render-compositor.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cairo-xlib-render-compositor.c b/src/cairo-xlib-render-compositor.c index e90df09..8a1ec7b 100644 --- a/src/cairo-xlib-render-compositor.c +++ b/src/cairo-xlib-render-compositor.c @@ -1287,6 +1287,9 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display, unsigned char *d; unsigned char *new, *n; + if (c == 0) + break; + new = malloc (c); if (!new) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -1312,6 +1315,9 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display, const uint32_t *d; uint32_t *new, *n; + if (c == 0) + break; + new = malloc (4 * c); if (unlikely (new == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); -- 2.3.1 1.1 x11-libs/cairo/files/cairo-1.14.0-tor-scan-converter-do_fullrow-intersection.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-tor-scan-converter-do_fullrow-intersection.patch?rev=1.1&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-tor-scan-converter-do_fullrow-intersection.patch?rev=1.1&content-type=text/plain Index: cairo-1.14.0-tor-scan-converter-do_fullrow-intersection.patch =================================================================== >From 2de69581c28bf115852037ca41eba13cb7335976 Mon Sep 17 00:00:00 2001 From: Massimo Valentini <mvalent...@src.gnome.org> Date: Sun, 19 Oct 2014 09:19:10 +0200 Subject: [PATCH] tor-scan-converter: can't do_fullrow when intersection in row + 0.5subrow the active edges list must be left sorted at the next possible use and since full_row does not deal with intersections it is not usable when there is an intersection in the top half of the next row first subrow Reported-and-tested-by: Matthew Leach Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85151 Reviewed-by: Chris Wilson <ch...@chris-wilson.co.uk> --- src/cairo-tor-scan-converter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cairo-tor-scan-converter.c b/src/cairo-tor-scan-converter.c index 4adcafb..14922d0 100644 --- a/src/cairo-tor-scan-converter.c +++ b/src/cairo-tor-scan-converter.c @@ -1167,8 +1167,8 @@ can_do_full_row (struct active_list *active) if (e->dy) { struct quorem x = e->x; - x.quo += e->dxdy_full.quo - e->dxdy.quo/2; - x.rem += e->dxdy_full.rem - e->dxdy.rem/2; + x.quo += e->dxdy_full.quo; + x.rem += e->dxdy_full.rem; if (x.rem < 0) { x.quo--; x.rem += e->dy; -- 2.3.1 1.1 x11-libs/cairo/files/cairo-1.14.0-CFF-unaligned-access.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-CFF-unaligned-access.patch?rev=1.1&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-CFF-unaligned-access.patch?rev=1.1&content-type=text/plain Index: cairo-1.14.0-CFF-unaligned-access.patch =================================================================== >From 99a35dd273f3deb4ae54310f1ed1746bfd9fae70 Mon Sep 17 00:00:00 2001 From: Adrian Johnson <ajohn...@redneon.com> Date: Sun, 19 Oct 2014 11:34:34 +1030 Subject: [PATCH] CFF: Fix unaligned access Debian bug 712836 reported bus errors in cff subsetting when running on a sparc. This is because unlike truetype, all data in the compact font format is not aligned. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=712836 --- src/cairo-cff-subset.c | 35 +++++++++++++++++++---------------- src/cairo-image-info.c | 32 +++++++++++++------------------- src/cairoint.h | 26 ++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c index 4660d6e..f15deb5 100644 --- a/src/cairo-cff-subset.c +++ b/src/cairo-cff-subset.c @@ -433,7 +433,7 @@ cff_index_read (cairo_array_t *index, unsigned char **ptr, unsigned char *end_pt p = *ptr; if (p + 2 > end_ptr) return CAIRO_INT_STATUS_UNSUPPORTED; - count = be16_to_cpu( *((uint16_t *)p) ); + count = get_unaligned_be16 (p); p += 2; if (count > 0) { offset_size = *p++; @@ -984,14 +984,14 @@ cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p) for (i = 0; i < font->num_glyphs; i++) font->fdselect[i] = *p++; } else if (type == 3) { - num_ranges = be16_to_cpu( *((uint16_t *)p) ); + num_ranges = get_unaligned_be16 (p); p += 2; for (i = 0; i < num_ranges; i++) { - first = be16_to_cpu( *((uint16_t *)p) ); + first = get_unaligned_be16 (p); p += 2; fd = *p++; - last = be16_to_cpu( *((uint16_t *)p) ); + last = get_unaligned_be16 (p); for (j = first; j < last; j++) font->fdselect[j] = fd; } @@ -1722,7 +1722,7 @@ cairo_cff_font_get_gid_for_cid (cairo_cff_font_t *font, unsigned long cid, unsi p = font->charset + 1; g = 1; while (g <= (unsigned)font->num_glyphs && p < font->data_end) { - c = be16_to_cpu( *((uint16_t *)p) ); + c = get_unaligned_be16 (p); if (c == cid) { *gid = g; return CAIRO_STATUS_SUCCESS; @@ -1737,7 +1737,7 @@ cairo_cff_font_get_gid_for_cid (cairo_cff_font_t *font, unsigned long cid, unsi first_gid = 1; p = font->charset + 1; while (first_gid <= (unsigned)font->num_glyphs && p + 2 < font->data_end) { - first_cid = be16_to_cpu( *((uint16_t *)p) ); + first_cid = get_unaligned_be16 (p); num_left = p[2]; if (cid >= first_cid && cid <= first_cid + num_left) { *gid = first_gid + cid - first_cid; @@ -1753,8 +1753,8 @@ cairo_cff_font_get_gid_for_cid (cairo_cff_font_t *font, unsigned long cid, unsi first_gid = 1; p = font->charset + 1; while (first_gid <= (unsigned)font->num_glyphs && p + 3 < font->data_end) { - first_cid = be16_to_cpu( *((uint16_t *)p) ); - num_left = be16_to_cpu( *((uint16_t *)(p+2)) ); + first_cid = get_unaligned_be16 (p); + num_left = get_unaligned_be16 (p+2); if (cid >= first_cid && cid <= first_cid + num_left) { *gid = first_gid + cid - first_cid; return CAIRO_STATUS_SUCCESS; @@ -2328,7 +2328,7 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font) unsigned int i; cairo_int_status_t status; unsigned int offset_array; - uint32_t *offset_array_ptr; + unsigned char *offset_array_ptr; int offset_base; uint16_t count; uint8_t offset_size = 4; @@ -2349,7 +2349,7 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font) if (unlikely (status)) return status; offset_base = _cairo_array_num_elements (&font->output) - 1; - *offset_array_ptr = cpu_to_be32(1); + put_unaligned_be32(1, offset_array_ptr); offset_array += sizeof(uint32_t); for (i = 0; i < font->num_subset_fontdicts; i++) { status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]], @@ -2357,8 +2357,9 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font) if (unlikely (status)) return status; - offset_array_ptr = (uint32_t *) _cairo_array_index (&font->output, offset_array); - *offset_array_ptr = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base); + offset_array_ptr = _cairo_array_index (&font->output, offset_array); + put_unaligned_be32 (_cairo_array_num_elements (&font->output) - offset_base, + offset_array_ptr); offset_array += sizeof(uint32_t); } @@ -2609,7 +2610,7 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font) unsigned int i; tt_hhea_t hhea; int num_hmetrics; - unsigned char buf[10]; + uint16_t short_entry; int glyph_index; cairo_int_status_t status; @@ -2629,7 +2630,8 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font) status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_hmtx, glyph_index * long_entry_size, - buf, &short_entry_size); + (unsigned char *) &short_entry, + &short_entry_size); if (unlikely (status)) return status; } @@ -2638,11 +2640,12 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font) status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_hmtx, (num_hmetrics - 1) * long_entry_size, - buf, &short_entry_size); + (unsigned char *) &short_entry, + &short_entry_size); if (unlikely (status)) return status; } - font->widths[i] = be16_to_cpu (*((int16_t*)buf)); + font->widths[i] = be16_to_cpu (short_entry); } return CAIRO_STATUS_SUCCESS; diff --git a/src/cairo-image-info.c b/src/cairo-image-info.c index 64053a2..26e7ae5 100644 --- a/src/cairo-image-info.c +++ b/src/cairo-image-info.c @@ -39,12 +39,6 @@ #include "cairo-error-private.h" #include "cairo-image-info-private.h" -static uint32_t -_get_be32 (const unsigned char *p) -{ - return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; -} - /* JPEG (image/jpeg) * * http://www.w3.org/Graphics/JPEG/itu-t81.pdf @@ -170,7 +164,7 @@ static const unsigned char _jpx_signature[] = { static const unsigned char * _jpx_next_box (const unsigned char *p) { - return p + _get_be32 (p); + return p + get_unaligned_be32 (p); } static const unsigned char * @@ -185,8 +179,8 @@ _jpx_match_box (const unsigned char *p, const unsigned char *end, uint32_t type) uint32_t length; if (p + 8 < end) { - length = _get_be32 (p); - if (_get_be32 (p + 4) == type && p + length < end) + length = get_unaligned_be32 (p); + if (get_unaligned_be32 (p + 4) == type && p + length < end) return TRUE; } @@ -208,8 +202,8 @@ _jpx_find_box (const unsigned char *p, const unsigned char *end, uint32_t type) static void _jpx_extract_info (const unsigned char *p, cairo_image_info_t *info) { - info->height = _get_be32 (p); - info->width = _get_be32 (p + 4); + info->height = get_unaligned_be32 (p); + info->width = get_unaligned_be32 (p + 4); info->num_components = (p[8] << 8) + p[9]; info->bits_per_component = p[10]; } @@ -281,13 +275,13 @@ _cairo_image_info_get_png_info (cairo_image_info_t *info, return CAIRO_INT_STATUS_UNSUPPORTED; p += 4; - if (_get_be32 (p) != PNG_IHDR) + if (get_unaligned_be32 (p) != PNG_IHDR) return CAIRO_INT_STATUS_UNSUPPORTED; p += 4; - info->width = _get_be32 (p); + info->width = get_unaligned_be32 (p); p += 4; - info->height = _get_be32 (p); + info->height = get_unaligned_be32 (p); return CAIRO_STATUS_SUCCESS; } @@ -347,14 +341,14 @@ _jbig2_get_next_segment (const unsigned char *p, if (p + 6 >= end) return NULL; - seg_num = _get_be32 (p); + seg_num = get_unaligned_be32 (p); *type = p[4] & 0x3f; big_page_size = (p[4] & 0x40) != 0; p += 5; num_segs = p[0] >> 5; if (num_segs == 7) { - num_segs = _get_be32 (p) & 0x1fffffff; + num_segs = get_unaligned_be32 (p) & 0x1fffffff; ref_seg_bytes = 4 + ((num_segs + 1)/8); } else { ref_seg_bytes = 1; @@ -373,7 +367,7 @@ _jbig2_get_next_segment (const unsigned char *p, if (p + 4 >= end) return NULL; - *data_len = _get_be32 (p); + *data_len = get_unaligned_be32 (p); p += 4; *data = p; @@ -397,8 +391,8 @@ _jbig2_get_next_segment (const unsigned char *p, static void _jbig2_extract_info (cairo_image_info_t *info, const unsigned char *p) { - info->width = _get_be32 (p); - info->height = _get_be32 (p + 4); + info->width = get_unaligned_be32 (p); + info->height = get_unaligned_be32 (p + 4); info->num_components = 1; info->bits_per_component = 1; } diff --git a/src/cairoint.h b/src/cairoint.h index b4e8ac8..07ced42 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -240,6 +240,32 @@ be32_to_cpu(uint32_t v) #endif +/* Unaligned big endian access + */ + +static inline uint16_t get_unaligned_be16 (const unsigned char *p) +{ + return p[0] << 8 | p[1]; +} + +static inline uint32_t get_unaligned_be32 (const unsigned char *p) +{ + return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; +} + +static inline void put_unaligned_be16 (uint16_t v, unsigned char *p) +{ + p[0] = (v >> 8) & 0xff; + p[1] = v & 0xff; +} + +static inline void put_unaligned_be32 (uint32_t v, unsigned char *p) +{ + p[0] = (v >> 24) & 0xff; + p[1] = (v >> 16) & 0xff; + p[2] = (v >> 8) & 0xff; + p[3] = v & 0xff; +} /* The glibc versions of ispace() and isdigit() are slow in UTF-8 locales. */ -- 2.3.1 1.1 x11-libs/cairo/files/cairo-1.14.0-image-negative-span-length.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-image-negative-span-length.patch?rev=1.1&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-libs/cairo/files/cairo-1.14.0-image-negative-span-length.patch?rev=1.1&content-type=text/plain Index: cairo-1.14.0-image-negative-span-length.patch =================================================================== >From 5c82d91a5e15d29b1489dcb413b24ee7fdf59934 Mon Sep 17 00:00:00 2001 From: Bryce Harrington <br...@osg.samsung.com> Date: Wed, 3 Dec 2014 19:28:15 -0800 Subject: [PATCH] image: Fix crash in _fill_xrgb32_lerp_opaque_spans If a span length is negative don't go out of bounds processing the fill data. Patch thanks to Ilya Sakhnenko <ilia.soft...@gmail.com> on mailing list. Signed-off-by: Bryce Harrington <br...@osg.samsung.com> --- src/cairo-image-compositor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index 6ff0f09..48072f8 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -2242,10 +2242,10 @@ _fill_xrgb32_lerp_opaque_spans (void *abstract_renderer, int y, int h, 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--) + while (len-- > 0) *d++ = r->u.fill.pixel; } - } else while (len--) { + } else while (len-- > 0) { *d = lerp8x4 (r->u.fill.pixel, a, *d); d++; } -- 2.3.1