From 414e334e3a773e05ecd1913ac0d237b0073a19b6 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sun, 22 Aug 2021 21:06:32 +0100 Subject: [PATCH] cairo: add package Cairo is a graphics drawing library. Signed-off-by: Daniel Golle --- libs/cairo/Makefile | 75 +++++++++++ libs/cairo/patches/001-musl-stacksize.patch | 23 ++++ libs/cairo/patches/002-CVE-2018-19876.patch | 25 ++++ libs/cairo/patches/003-pdf-flush.patch | 28 ++++ ...4-fix-mask-usage-in-image-compositor.patch | 120 ++++++++++++++++++ .../patches/005-composite_color_glyphs.patch | 56 ++++++++ ...array-of-operands-for-certain-operat.patch | 114 +++++++++++++++++ 7 files changed, 441 insertions(+) create mode 100644 libs/cairo/Makefile create mode 100644 libs/cairo/patches/001-musl-stacksize.patch create mode 100644 libs/cairo/patches/002-CVE-2018-19876.patch create mode 100644 libs/cairo/patches/003-pdf-flush.patch create mode 100644 libs/cairo/patches/004-fix-mask-usage-in-image-compositor.patch create mode 100644 libs/cairo/patches/005-composite_color_glyphs.patch create mode 100644 libs/cairo/patches/006-cff-allow-empty-array-of-operands-for-certain-operat.patch diff --git a/libs/cairo/Makefile b/libs/cairo/Makefile new file mode 100644 index 0000000..dc3baf4 --- /dev/null +++ b/libs/cairo/Makefile @@ -0,0 +1,75 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=cairo +PKG_VERSION:=1.16.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=https://cairo.freedesktop.org/releases/ +PKG_HASH:=5e7b29b3f113ef870d1e3ecf8adf21f923396401604bda16d44be45e66052331 + +PKG_MAINTAINER:=Daniel Golle +PKG_LICENSE:=LGPL-2.1-or-later MPL-1.1 +PKG_LICENSE_FILES:=COPYING COPYING-LGPL-2.1 COPYING-MPL-1.1 + +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/libcairo + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=Video + TITLE:=cairo + URL:=https://cairo.freedesktop.org/ + DEPENDS:=+libpng +libfreetype +fontconfig +libmesa +pixman +glib2 +libjpeg +zlib +endef + +define Package/libcairo/description + Cairo is a 2D graphics library with support for multiple output devices. +endef + +CONFIGURE_ARGS += \ + --oldincludedir="$(STAGING_DIR)/usr/include" \ + --x-includes="$(STAGING_DIR)/usr/include" \ + --x-libraries="$(STAGING_DIR)/usr/lib" \ + --without-x \ + --without-gallium \ + --enable-pdf \ + --enable-png \ + --enable-ps \ + --enable-svg \ + --enable-tee \ + --enable-ft \ + --enable-glesv3 \ + --enable-test-surfaces=no \ + --enable-drm=no \ + --enable-gallium=no \ + --enable-x=no \ + --enable-xcb=no \ + --enable-xlib-xrender=no \ + --enable-xcb=no \ + --enable-xlib-xcb=no \ + --enable-xcb-shm=no + +define Package/libcairo/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/lib/cairo + $(CP) $(PKG_INSTALL_DIR)/usr/lib/cairo/*.so $(1)/usr/lib/cairo +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/cairo + $(CP) $(PKG_INSTALL_DIR)/usr/include/cairo/*.h $(1)/usr/include/cairo + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/lib/cairo + $(CP) $(PKG_INSTALL_DIR)/usr/lib/cairo/*.so $(1)/usr/lib/cairo + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc $(1)/usr/lib/pkgconfig +endef + +$(eval $(call BuildPackage,libcairo)) diff --git a/libs/cairo/patches/001-musl-stacksize.patch b/libs/cairo/patches/001-musl-stacksize.patch new file mode 100644 index 0000000..3f97334 --- /dev/null +++ b/libs/cairo/patches/001-musl-stacksize.patch @@ -0,0 +1,23 @@ +Reduce the footprint of stack frame usage by turning +some large(r) structures as `static __thread` instead. + +--- a/src/cairo-rectangular-scan-converter.c ++++ b/src/cairo-rectangular-scan-converter.c +@@ -489,7 +489,7 @@ generate (cairo_rectangular_scan_convert + cairo_span_renderer_t *renderer, + rectangle_t **rectangles) + { +- sweep_line_t sweep_line; ++ static __thread sweep_line_t sweep_line; + rectangle_t *start, *stop; + cairo_status_t status; + +@@ -656,7 +656,7 @@ _cairo_rectangular_scan_converter_genera + cairo_span_renderer_t *renderer) + { + cairo_rectangular_scan_converter_t *self = converter; +- rectangle_t *rectangles_stack[CAIRO_STACK_ARRAY_LENGTH (rectangle_t *)]; ++ static __thread rectangle_t *rectangles_stack[CAIRO_STACK_ARRAY_LENGTH (rectangle_t *)]; + rectangle_t **rectangles; + struct _cairo_rectangular_scan_converter_chunk *chunk; + cairo_status_t status; diff --git a/libs/cairo/patches/002-CVE-2018-19876.patch b/libs/cairo/patches/002-CVE-2018-19876.patch new file mode 100644 index 0000000..ea88bea --- /dev/null +++ b/libs/cairo/patches/002-CVE-2018-19876.patch @@ -0,0 +1,25 @@ +From 90e85c2493fdfa3551f202ff10282463f1e36645 Mon Sep 17 00:00:00 2001 +From: Carlos Garcia Campos +Date: Mon, 19 Nov 2018 12:33:07 +0100 +Subject: [PATCH] ft: Use FT_Done_MM_Var instead of free when available in + cairo_ft_apply_variations + +Fixes a crash when using freetype >= 2.9 +--- + src/cairo-ft-font.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/src/cairo-ft-font.c ++++ b/src/cairo-ft-font.c +@@ -2393,7 +2393,11 @@ skip: + done: + free (coords); + free (current_coords); ++#if HAVE_FT_DONE_MM_VAR ++ FT_Done_MM_Var (face->glyph->library, ft_mm_var); ++#else + free (ft_mm_var); ++#endif + } + } + diff --git a/libs/cairo/patches/003-pdf-flush.patch b/libs/cairo/patches/003-pdf-flush.patch new file mode 100644 index 0000000..4f56f9a --- /dev/null +++ b/libs/cairo/patches/003-pdf-flush.patch @@ -0,0 +1,28 @@ +From https://cgit.freedesktop.org/cairo/commit/?id=4c8813f0eaacc32c27126ad2296951a626300b89 + +Fixes https://gitlab.freedesktop.org/cairo/cairo/issues/342 + +From 4c8813f0eaacc32c27126ad2296951a626300b89 Mon Sep 17 00:00:00 2001 +From: Adrian Johnson +Date: Thu, 25 Oct 2018 18:46:17 +1030 +Subject: pdf: add missing flush + +Issue #342 +--- + src/cairo-pdf-surface.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/src/cairo-pdf-surface.c ++++ b/src/cairo-pdf-surface.c +@@ -7711,6 +7711,11 @@ _cairo_pdf_surface_mask (void *abstrac + * and most common, case to handle. */ + if (_cairo_pattern_is_constant_alpha (mask, &extents.bounded, &alpha) && + _can_paint_pattern (source)) { ++ ++ status = _cairo_pdf_operators_flush (&surface->pdf_operators); ++ if (unlikely (status)) ++ goto cleanup; ++ + _cairo_output_stream_printf (surface->output, "q\n"); + status = _cairo_pdf_surface_paint_pattern (surface, + op, diff --git a/libs/cairo/patches/004-fix-mask-usage-in-image-compositor.patch b/libs/cairo/patches/004-fix-mask-usage-in-image-compositor.patch new file mode 100644 index 0000000..2c2e51f --- /dev/null +++ b/libs/cairo/patches/004-fix-mask-usage-in-image-compositor.patch @@ -0,0 +1,120 @@ +From 03a820b173ed1fdef6ff14b4468f5dbc02ff59be Mon Sep 17 00:00:00 2001 +From: Heiko Lewin +Date: Tue, 15 Dec 2020 16:48:19 +0100 +Subject: [PATCH 1/3] Fix mask usage in image-compositor + +--- + src/cairo-image-compositor.c | 8 ++-- + test/Makefile.sources | 1 + + test/bug-image-compositor.c | 39 ++++++++++++++++++++ + test/reference/bug-image-compositor.ref.png | Bin 0 -> 185 bytes + 4 files changed, 44 insertions(+), 4 deletions(-) + create mode 100644 test/bug-image-compositor.c + create mode 100644 test/reference/bug-image-compositor.ref.png + +--- a/src/cairo-image-compositor.c ++++ b/src/cairo-image-compositor.c +@@ -2601,14 +2601,14 @@ _inplace_src_spans (void *abstract_rende + unsigned num_spans) + { + cairo_image_span_renderer_t *r = abstract_renderer; +- uint8_t *m; ++ uint8_t *m, *base = (uint8_t*)pixman_image_get_data(r->mask); + int x0; + + if (num_spans == 0) + return CAIRO_STATUS_SUCCESS; + + x0 = spans[0].x; +- m = r->_buf; ++ m = base; + do { + int len = spans[1].x - spans[0].x; + if (len >= r->u.composite.run_length && spans[0].coverage == 0xff) { +@@ -2646,7 +2646,7 @@ _inplace_src_spans (void *abstract_rende + spans[0].x, y, + spans[1].x - spans[0].x, h); + +- m = r->_buf; ++ m = base; + x0 = spans[1].x; + } else if (spans[0].coverage == 0x0) { + if (spans[0].x != x0) { +@@ -2675,7 +2675,7 @@ _inplace_src_spans (void *abstract_rende + #endif + } + +- m = r->_buf; ++ m = base; + x0 = spans[1].x; + } else { + *m++ = spans[0].coverage; +--- /dev/null ++++ b/test/bug-image-compositor.c +@@ -0,0 +1,66 @@ ++/* ++ * Copyright © 2020 Uli Schlachter, Heiko Lewin ++ * ++ * Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, ++ * modify, merge, publish, distribute, sublicense, and/or sell copies ++ * of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ * ++ * Author: Uli Schlachter ++ * Author: Heiko Lewin ++ */ ++#include "cairo-test.h" ++ ++ ++/* This test reproduces an overflow of a mask-buffer in cairo-image-compositor.c */ ++ ++static cairo_test_status_t ++draw (cairo_t *cr, int width, int height) ++{ ++ cairo_set_source_rgb (cr, 0., 0., 0.); ++ cairo_paint (cr); ++ ++ cairo_set_source_rgb (cr, 1., 1., 1.); ++ cairo_set_line_width (cr, 1.); ++ ++ cairo_pattern_t *p = cairo_pattern_create_linear (0, 0, width, height); ++ cairo_pattern_add_color_stop_rgb (p, 0, 0.99, 1, 1); ++ cairo_pattern_add_color_stop_rgb (p, 1, 1, 1, 1); ++ cairo_set_source (cr, p); ++ cairo_pattern_destroy(p); ++ ++ cairo_move_to (cr, 0.5, -1); ++ for (int i = 0; i < width; i+=3) { ++ cairo_rel_line_to (cr, 2, 2); ++ cairo_rel_line_to (cr, 1, -2); ++ } ++ ++ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); ++ cairo_stroke (cr); ++ ++ return CAIRO_TEST_SUCCESS; ++} ++ ++ ++CAIRO_TEST (bug_image_compositor, ++ "Crash in image-compositor", ++ "stroke, stress", /* keywords */ ++ NULL, /* requirements */ ++ 10000, 1, ++ NULL, draw) ++ diff --git a/libs/cairo/patches/005-composite_color_glyphs.patch b/libs/cairo/patches/005-composite_color_glyphs.patch new file mode 100644 index 0000000..407e9b4 --- /dev/null +++ b/libs/cairo/patches/005-composite_color_glyphs.patch @@ -0,0 +1,56 @@ +From 79ad01724161502e8d9d2bd384ff1f0174e5df6e Mon Sep 17 00:00:00 2001 +From: Matthias Clasen +Date: Thu, 30 May 2019 07:30:55 -0400 +Subject: [PATCH] Fix a thinko in composite_color_glyphs + +We can't just move around the contents of the +passed-in string, we need to make a copy. This +was showing up as memory corruption in pango. + +See https://gitlab.gnome.org/GNOME/pango/issues/346 +--- + src/cairo-surface.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +Patch-Source: https://github.com/matthiasclasen/cairo/commit/79ad01724161502e8d9d2bd384ff1f0174e5df6e + +--- a/src/cairo-surface.c ++++ b/src/cairo-surface.c +@@ -2820,6 +2820,7 @@ _cairo_surface_show_text_glyphs (cairo_s + const cairo_clip_t *clip) + { + cairo_int_status_t status; ++ char *utf8_copy = NULL; + + TRACE ((stderr, "%s\n", __FUNCTION__)); + if (unlikely (surface->status)) +@@ -2847,6 +2848,10 @@ _cairo_surface_show_text_glyphs (cairo_s + status = CAIRO_INT_STATUS_UNSUPPORTED; + + if (_cairo_scaled_font_has_color_glyphs (scaled_font)) { ++ utf8_copy = malloc (sizeof (char) * utf8_len); ++ memcpy (utf8_copy, utf8, sizeof (char) * utf8_len); ++ utf8 = utf8_copy; ++ + status = composite_color_glyphs (surface, op, + source, + (char *)utf8, &utf8_len, +@@ -2861,6 +2866,8 @@ _cairo_surface_show_text_glyphs (cairo_s + if (num_glyphs == 0) + goto DONE; + } ++ else ++ utf8_copy = NULL; + + /* The logic here is duplicated in _cairo_analysis_surface show_glyphs and + * show_text_glyphs. Keep in synch. */ +@@ -2918,6 +2925,9 @@ DONE: + surface->serial++; + } + ++ if (utf8_copy) ++ free (utf8_copy); ++ + return _cairo_surface_set_error (surface, status); + } + diff --git a/libs/cairo/patches/006-cff-allow-empty-array-of-operands-for-certain-operat.patch b/libs/cairo/patches/006-cff-allow-empty-array-of-operands-for-certain-operat.patch new file mode 100644 index 0000000..b750e46 --- /dev/null +++ b/libs/cairo/patches/006-cff-allow-empty-array-of-operands-for-certain-operat.patch @@ -0,0 +1,114 @@ +From ef959bc76e65ea0b0d4ba3ee50dfbce31c3484ad Mon Sep 17 00:00:00 2001 +From: Marek Kasik +Date: Fri, 27 Mar 2020 19:39:46 +0100 +Subject: [PATCH] cff: Allow empty array of operands for certain operators + +Operators BlueValues, OtherBlues, FamilyBlues, FamilyOtherBlues, +StemSnapH and StemSnapV have operands of type delta which can be +a number or an array of delta-encoded numbers. This array can be +empty according to freetype developers. +This commit checks whether current operator is among those listed +and permits empty operand in such case. +--- + src/cairo-cff-subset.c | 78 ++++++++++++++++++++++++++---------------- + 1 file changed, 49 insertions(+), 29 deletions(-) + +Patch-Source: https://src.fedoraproject.org/rpms/cairo/blob/ba42ecc23bb1162a1951edc0209f9f48e87bba7e/f/0001-cff-Allow-empty-array-of-operands-for-certain-operat.patch +See-Also: https://bugzilla.redhat.com/show_bug.cgi?id=1817958 + +--- a/src/cairo-cff-subset.c ++++ b/src/cairo-cff-subset.c +@@ -56,30 +56,36 @@ + + /* CFF Dict Operators. If the high byte is 0 the command is encoded + * with a single byte. */ +-#define BASEFONTNAME_OP 0x0c16 +-#define CIDCOUNT_OP 0x0c22 +-#define CHARSET_OP 0x000f +-#define CHARSTRINGS_OP 0x0011 +-#define COPYRIGHT_OP 0x0c00 +-#define DEFAULTWIDTH_OP 0x0014 +-#define ENCODING_OP 0x0010 +-#define FAMILYNAME_OP 0x0003 +-#define FDARRAY_OP 0x0c24 +-#define FDSELECT_OP 0x0c25 +-#define FONTBBOX_OP 0x0005 +-#define FONTMATRIX_OP 0x0c07 +-#define FONTNAME_OP 0x0c26 +-#define FULLNAME_OP 0x0002 +-#define LOCAL_SUB_OP 0x0013 +-#define NOMINALWIDTH_OP 0x0015 +-#define NOTICE_OP 0x0001 +-#define POSTSCRIPT_OP 0x0c15 +-#define PRIVATE_OP 0x0012 +-#define ROS_OP 0x0c1e +-#define UNIQUEID_OP 0x000d +-#define VERSION_OP 0x0000 +-#define WEIGHT_OP 0x0004 +-#define XUID_OP 0x000e ++#define BASEFONTNAME_OP 0x0c16 ++#define CIDCOUNT_OP 0x0c22 ++#define CHARSET_OP 0x000f ++#define CHARSTRINGS_OP 0x0011 ++#define COPYRIGHT_OP 0x0c00 ++#define DEFAULTWIDTH_OP 0x0014 ++#define ENCODING_OP 0x0010 ++#define FAMILYNAME_OP 0x0003 ++#define FDARRAY_OP 0x0c24 ++#define FDSELECT_OP 0x0c25 ++#define FONTBBOX_OP 0x0005 ++#define FONTMATRIX_OP 0x0c07 ++#define FONTNAME_OP 0x0c26 ++#define FULLNAME_OP 0x0002 ++#define LOCAL_SUB_OP 0x0013 ++#define NOMINALWIDTH_OP 0x0015 ++#define NOTICE_OP 0x0001 ++#define POSTSCRIPT_OP 0x0c15 ++#define PRIVATE_OP 0x0012 ++#define ROS_OP 0x0c1e ++#define UNIQUEID_OP 0x000d ++#define VERSION_OP 0x0000 ++#define WEIGHT_OP 0x0004 ++#define XUID_OP 0x000e ++#define BLUEVALUES_OP 0x0006 ++#define OTHERBLUES_OP 0x0007 ++#define FAMILYBLUES_OP 0x0008 ++#define FAMILYOTHERBLUES_OP 0x0009 ++#define STEMSNAPH_OP 0x0c0c ++#define STEMSNAPV_OP 0x0c0d + + #define NUM_STD_STRINGS 391 + +@@ -615,13 +621,27 @@ cff_dict_create_operator (int + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + _cairo_dict_init_key (op, operator); +- op->operand = _cairo_malloc (size); +- if (unlikely (op->operand == NULL)) { +- free (op); +- return _cairo_error (CAIRO_STATUS_NO_MEMORY); ++ if (size != 0) { ++ op->operand = _cairo_malloc (size); ++ if (unlikely (op->operand == NULL)) { ++ free (op); ++ return _cairo_error (CAIRO_STATUS_NO_MEMORY); ++ } ++ memcpy (op->operand, operand, size); ++ } else { ++ op->operand = NULL; ++ /* Delta-encoded arrays can be empty. */ ++ if (operator != BLUEVALUES_OP && ++ operator != OTHERBLUES_OP && ++ operator != FAMILYBLUES_OP && ++ operator != FAMILYOTHERBLUES_OP && ++ operator != STEMSNAPH_OP && ++ operator != STEMSNAPV_OP) { ++ free (op); ++ return _cairo_error (CAIRO_STATUS_NO_MEMORY); ++ } + } + +- memcpy (op->operand, operand, size); + op->operand_length = size; + op->operand_offset = -1; + -- 2.30.2