import librsvg2-2.42.7-4.el8

This commit is contained in:
CentOS Sources 2020-07-28 06:31:34 -04:00 committed by Stepan Oksanichenko
parent 3bb9faf997
commit 5302fc94b2
3 changed files with 665 additions and 2 deletions

View File

@ -0,0 +1,573 @@
From faec595a1721a2496e9c258917facbb564f85854 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 13 May 2020 17:53:13 -0500
Subject: [PATCH] CVE-2019-20446.patch
---
librsvg/rsvg-base.c | 90 +++++++++---
librsvg/rsvg-private.h | 5 +-
rsvg_internals/src/drawing_ctx.rs | 23 ++--
rsvg_internals/src/structure.rs | 21 ++-
tests/errors.c | 52 ++++++-
.../errors/308-doubly-recursive-use.svg | 13 ++
tests/fixtures/errors/308-recursive-use.svg | 9 ++
tests/fixtures/errors/308-use-self-ref.svg | 7 +
.../errors/515-pattern-billion-laughs.svg | 130 ++++++++++++++++++
.../errors/515-too-many-elements.svgz | Bin 0 -> 40811 bytes
10 files changed, 310 insertions(+), 40 deletions(-)
create mode 100644 tests/fixtures/errors/308-doubly-recursive-use.svg
create mode 100644 tests/fixtures/errors/308-recursive-use.svg
create mode 100644 tests/fixtures/errors/308-use-self-ref.svg
create mode 100644 tests/fixtures/errors/515-pattern-billion-laughs.svg
create mode 100644 tests/fixtures/errors/515-too-many-elements.svgz
diff --git a/librsvg/rsvg-base.c b/librsvg/rsvg-base.c
index dbad819..af3d43c 100644
--- a/librsvg/rsvg-base.c
+++ b/librsvg/rsvg-base.c
@@ -431,12 +431,29 @@ node_set_atts (RsvgNode * node, RsvgHandle *handle, const NodeCreator *creator,
}
}
+static gboolean
+loading_limits_exceeded (RsvgHandle *handle)
+{
+ /* This is a mitigation for SVG files which create millions of elements
+ * in an attempt to exhaust memory. We don't allow loading more than
+ * this number of elements during the initial streaming load process.
+ */
+ return handle->priv->num_loaded_elements > 200000;
+}
+
static void
rsvg_standard_element_start (RsvgHandle *handle, const char *name, RsvgPropertyBag * atts)
{
const NodeCreator *creator;
RsvgNode *newnode = NULL;
+ if (loading_limits_exceeded (handle)) {
+ g_set_error (handle->priv->error, RSVG_ERROR, 0, "instancing limit");
+
+ xmlStopParser (handle->priv->ctxt);
+ return;
+ }
+
creator = get_node_creator_for_element_name (name);
g_assert (creator != NULL && creator->create_fn != NULL);
@@ -456,6 +473,7 @@ rsvg_standard_element_start (RsvgHandle *handle, const char *name, RsvgPropertyB
handle->priv->treebase = rsvg_node_ref (newnode);
}
+ handle->priv->num_loaded_elements += 1;
handle->priv->currentnode = rsvg_node_ref (newnode);
node_set_atts (newnode, handle, creator, atts);
@@ -1641,6 +1659,52 @@ rsvg_push_discrete_layer (RsvgDrawingCtx * ctx)
ctx->render->push_discrete_layer (ctx);
}
+void
+rsvg_drawing_ctx_increase_num_elements_acquired (RsvgDrawingCtx *draw_ctx)
+{
+ draw_ctx->num_elements_acquired++;
+}
+
+/* This is a mitigation for the security-related bugs:
+ * https://gitlab.gnome.org/GNOME/librsvg/issues/323
+ * https://gitlab.gnome.org/GNOME/librsvg/issues/515
+ *
+ * Imagine the XML [billion laughs attack], but done in SVG's terms:
+ *
+ * - #323 above creates deeply nested groups of `<use>` elements.
+ * The first one references the second one ten times, the second one
+ * references the third one ten times, and so on. In the file given,
+ * this causes 10^17 objects to be rendered. While this does not
+ * exhaust memory, it would take a really long time.
+ *
+ * - #515 has deeply nested references of `<pattern>` elements. Each
+ * object inside each pattern has an attribute
+ * fill="url(#next_pattern)", so the number of final rendered objects
+ * grows exponentially.
+ *
+ * We deal with both cases by placing a limit on how many references
+ * will be resolved during the SVG rendering process, that is,
+ * how many `url(#foo)` will be resolved.
+ *
+ * [billion laughs attack]: https://bitbucket.org/tiran/defusedxml
+ */
+static gboolean
+limits_exceeded (RsvgDrawingCtx *draw_ctx)
+{
+ return draw_ctx->num_elements_acquired > 500000;
+}
+
+RsvgNode *
+rsvg_drawing_ctx_acquire_node_ref (RsvgDrawingCtx * ctx, RsvgNode *node)
+{
+ if (g_slist_find (ctx->acquired_nodes, node))
+ return NULL;
+
+ ctx->acquired_nodes = g_slist_prepend (ctx->acquired_nodes, node);
+
+ return node;
+}
+
/*
* rsvg_drawing_ctx_acquire_node:
* @ctx: The drawing context in use
@@ -1668,16 +1732,15 @@ rsvg_drawing_ctx_acquire_node (RsvgDrawingCtx * ctx, const char *url)
if (url == NULL)
return NULL;
+ rsvg_drawing_ctx_increase_num_elements_acquired (ctx);
+ if (limits_exceeded (ctx))
+ return NULL;
+
node = rsvg_defs_lookup (ctx->defs, url);
if (node == NULL)
return NULL;
- if (g_slist_find (ctx->acquired_nodes, node))
- return NULL;
-
- ctx->acquired_nodes = g_slist_prepend (ctx->acquired_nodes, node);
-
- return node;
+ return rsvg_drawing_ctx_acquire_node_ref (ctx, node);
}
/**
@@ -1734,18 +1797,9 @@ rsvg_drawing_ctx_release_node (RsvgDrawingCtx * ctx, RsvgNode *node)
if (node == NULL)
return;
- g_return_if_fail (ctx->acquired_nodes != NULL);
- g_return_if_fail (ctx->acquired_nodes->data == node);
-
ctx->acquired_nodes = g_slist_remove (ctx->acquired_nodes, node);
}
-void
-rsvg_drawing_ctx_increase_num_elements_rendered_through_use (RsvgDrawingCtx *draw_ctx)
-{
- draw_ctx->num_elements_rendered_through_use++;
-}
-
void
rsvg_drawing_ctx_add_node_and_ancestors_to_stack (RsvgDrawingCtx *draw_ctx, RsvgNode *node)
{
@@ -1759,12 +1813,6 @@ rsvg_drawing_ctx_add_node_and_ancestors_to_stack (RsvgDrawingCtx *draw_ctx, Rsvg
}
}
-static gboolean
-limits_exceeded (RsvgDrawingCtx *draw_ctx)
-{
- return draw_ctx->num_elements_rendered_through_use > 500000;
-}
-
gboolean
rsvg_drawing_ctx_draw_node_from_stack (RsvgDrawingCtx *ctx, RsvgNode *node, int dominate)
{
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index aeec8d5..06f4c2b 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -164,6 +164,7 @@ struct RsvgHandlePrivate {
*/
RsvgSaxHandler *handler;
int handler_nest;
+ gsize num_loaded_elements;
GHashTable *entities; /* g_malloc'd string -> xmlEntityPtr */
@@ -200,7 +201,7 @@ struct RsvgDrawingCtx {
RsvgState *state;
GError **error;
RsvgDefs *defs;
- gsize num_elements_rendered_through_use;
+ gsize num_elements_acquired;
PangoContext *pango_context;
double dpi_x, dpi_y;
RsvgViewBox vb;
@@ -502,6 +503,8 @@ RsvgNode *rsvg_drawing_ctx_acquire_node (RsvgDrawingCtx * ctx, const cha
G_GNUC_INTERNAL
RsvgNode *rsvg_drawing_ctx_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, RsvgNodeType type);
G_GNUC_INTERNAL
+RsvgNode *rsvg_drawing_ctx_acquire_node_ref (RsvgDrawingCtx * ctx, RsvgNode *node);
+G_GNUC_INTERNAL
void rsvg_drawing_ctx_release_node (RsvgDrawingCtx * ctx, RsvgNode *node);
G_GNUC_INTERNAL
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 79f0c9f..631b073 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -32,6 +32,11 @@ extern "C" {
fn rsvg_drawing_ctx_pop_view_box(draw_ctx: *const RsvgDrawingCtx);
+ fn rsvg_drawing_ctx_acquire_node_ref(
+ draw_ctx: *const RsvgDrawingCtx,
+ node: *const RsvgNode,
+ ) -> *mut RsvgNode;
+
fn rsvg_drawing_ctx_acquire_node(
draw_ctx: *const RsvgDrawingCtx,
url: *const libc::c_char,
@@ -45,8 +50,6 @@ extern "C" {
fn rsvg_drawing_ctx_release_node(draw_ctx: *const RsvgDrawingCtx, node: *mut RsvgNode);
- fn rsvg_drawing_ctx_increase_num_elements_rendered_through_use(draw_ctx: *const RsvgDrawingCtx);
-
fn rsvg_drawing_ctx_get_current_state_affine(draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix;
fn rsvg_drawing_ctx_set_current_state_affine(
@@ -149,6 +152,16 @@ pub fn pop_view_box(draw_ctx: *const RsvgDrawingCtx) {
}
}
+pub fn acquire_node_ref(draw_ctx: *const RsvgDrawingCtx, node: *const RsvgNode) -> Option<AcquiredNode> {
+ let raw_node = unsafe { rsvg_drawing_ctx_acquire_node_ref(draw_ctx, node) };
+
+ if raw_node.is_null() {
+ None
+ } else {
+ Some(AcquiredNode(draw_ctx, raw_node))
+ }
+}
+
pub fn get_acquired_node(draw_ctx: *const RsvgDrawingCtx, url: &str) -> Option<AcquiredNode> {
let raw_node = unsafe { rsvg_drawing_ctx_acquire_node(draw_ctx, str::to_glib_none(url).0) };
@@ -290,12 +303,6 @@ pub fn state_pop(draw_ctx: *const RsvgDrawingCtx) {
}
}
-pub fn increase_num_elements_rendered_through_use(draw_ctx: *const RsvgDrawingCtx) {
- unsafe {
- rsvg_drawing_ctx_increase_num_elements_rendered_through_use(draw_ctx);
- }
-}
-
pub struct AcquiredNode(*const RsvgDrawingCtx, *mut RsvgNode);
impl Drop for AcquiredNode {
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 71c9ff0..e4234ae 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -278,6 +278,20 @@ impl NodeTrait for NodeUse {
return;
}
+ // <use> is an element that is used directly, unlike
+ // <pattern>, which is used through a fill="url(#...)"
+ // reference. However, <use> will always reference another
+ // element, potentially itself or an ancestor of itself (or
+ // another <use> which references the first one, etc.). So,
+ // we acquire the <use> element itself so that circular
+ // references can be caught.
+ let self_box = box_node(node.clone());
+ let self_acquired = drawing_ctx::acquire_node_ref(draw_ctx, self_box);
+ rsvg_node_unref(self_box);
+ if self_acquired.is_none() {
+ return;
+ }
+
let child = if let Some(acquired) =
drawing_ctx::get_acquired_node(draw_ctx, link.as_ref().unwrap())
{
@@ -286,13 +300,6 @@ impl NodeTrait for NodeUse {
return;
};
- if Node::is_ancestor(node.clone(), child.clone()) {
- // or, if we're <use>'ing ourselves
- return;
- }
-
- drawing_ctx::increase_num_elements_rendered_through_use(draw_ctx);
-
let nx = self.x.get().normalize(draw_ctx);
let ny = self.y.get().normalize(draw_ctx);
diff --git a/tests/errors.c b/tests/errors.c
index f370d60..ab5898a 100644
--- a/tests/errors.c
+++ b/tests/errors.c
@@ -22,10 +22,29 @@ get_test_filename (const char *basename) {
basename,
NULL);
}
+
+static void
+test_loading_error (gconstpointer data)
+{
+ const char *basename = data;
+ char *filename = get_test_filename (basename);
+ RsvgHandle *handle;
+ GError *error = NULL;
+
+ handle = rsvg_handle_new_from_file (filename, &error);
+ g_free (filename);
+
+ g_assert (handle == NULL);
+ g_assert (g_error_matches (error, RSVG_ERROR, RSVG_ERROR_FAILED));
+
+ g_error_free (error);
+}
+
static void
-test_instancing_limit (void)
+test_instancing_limit (gconstpointer data)
{
- char *filename = get_test_filename ("323-nested-use.svg");
+ const char *basename = data;
+ char *filename = get_test_filename (basename);
RsvgHandle *handle;
GError *error = NULL;
cairo_surface_t *surf;
@@ -49,7 +68,34 @@ main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
- g_test_add_func ("/errors/instancing_limit", test_instancing_limit);
+ g_test_add_data_func_full ("/errors/instancing_limit/323-nested-use.svg",
+ "323-nested-use.svg",
+ test_instancing_limit,
+ NULL);
+
+ g_test_add_data_func_full ("/errors/instancing_limit/515-pattern-billion-laughs.svg",
+ "515-pattern-billion-laughs.svg",
+ test_instancing_limit,
+ NULL);
+
+ g_test_add_data_func_full ("/errors/instancing_limit/308-use-self-ref.svg",
+ "308-use-self-ref.svg",
+ test_instancing_limit,
+ NULL);
+ g_test_add_data_func_full ("/errors/instancing_limit/308-recursive-use.svg",
+ "308-recursive-use.svg",
+ test_instancing_limit,
+ NULL);
+ g_test_add_data_func_full ("/errors/instancing_limit/308-doubly-recursive-use.svg",
+ "308-doubly-recursive-use.svg",
+ test_instancing_limit,
+ NULL);
+
+ g_test_add_data_func_full ("/errors/515-too-many-elements.svgz",
+ "515-too-many-elements.svgz",
+ test_loading_error,
+ NULL);
+
return g_test_run ();
}
diff --git a/tests/fixtures/errors/308-doubly-recursive-use.svg b/tests/fixtures/errors/308-doubly-recursive-use.svg
new file mode 100644
index 0000000..9b248a6
--- /dev/null
+++ b/tests/fixtures/errors/308-doubly-recursive-use.svg
@@ -0,0 +1,13 @@
+<svg>
+ <defs>
+ <g id="one">
+ <use xlink:href="#two"/>
+ </g>
+
+ <g id="two">
+ <use xlink:href="#one"/>
+ </g>
+ </defs>
+
+ <use xlink:href="#one"/>
+</svg>
diff --git a/tests/fixtures/errors/308-recursive-use.svg b/tests/fixtures/errors/308-recursive-use.svg
new file mode 100644
index 0000000..f5d00bf
--- /dev/null
+++ b/tests/fixtures/errors/308-recursive-use.svg
@@ -0,0 +1,9 @@
+<svg>
+ <defs>
+ <g id="one">
+ <use xlink:href="#one"/>
+ </g>
+ </defs>
+
+ <use xlink:href="#one"/>
+</svg>
diff --git a/tests/fixtures/errors/308-use-self-ref.svg b/tests/fixtures/errors/308-use-self-ref.svg
new file mode 100644
index 0000000..dbf14c5
--- /dev/null
+++ b/tests/fixtures/errors/308-use-self-ref.svg
@@ -0,0 +1,7 @@
+<svg>
+ <defs>
+ <use id="one" xlink:href="#one"/>
+ </defs>
+
+ <use xlink:href="#one"/>
+</svg>
diff --git a/tests/fixtures/errors/515-pattern-billion-laughs.svg b/tests/fixtures/errors/515-pattern-billion-laughs.svg
new file mode 100644
index 0000000..a306960
--- /dev/null
+++ b/tests/fixtures/errors/515-pattern-billion-laughs.svg
@@ -0,0 +1,130 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="40cm" height="20cm" viewBox="0 0 800 400" version="1.1"
+ xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <pattern id="z" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(10,10)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#i)" stroke="yellow"/>
+ </pattern>
+
+ <pattern id="i" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#h)" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="url(#h)" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="url(#h)" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="url(#h)" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="url(#h)" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="url(#h)" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="url(#h)" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="url(#h)" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="url(#h)" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="url(#h)" stroke="cyan" />
+ </pattern>
+
+ <pattern id="h" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#g)" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="url(#g)" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="url(#g)" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="url(#g)" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="url(#g)" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="url(#g)" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="url(#g)" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="url(#g)" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="url(#g)" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="url(#g)" stroke="cyan" />
+ </pattern>
+
+ <pattern id="g" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#f)" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="url(#f)" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="url(#f)" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="url(#f)" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="url(#f)" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="url(#f)" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="url(#f)" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="url(#f)" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="url(#f)" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="url(#f)" stroke="cyan" />
+ </pattern>
+
+ <pattern id="f" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#e)" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="url(#e)" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="url(#e)" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="url(#e)" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="url(#e)" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="url(#e)" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="url(#e)" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="url(#e)" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="url(#e)" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="url(#e)" stroke="cyan" />
+ </pattern>
+
+ <pattern id="e" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#d)" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="url(#d)" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="url(#d)" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="url(#d)" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="url(#d)" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="url(#d)" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="url(#d)" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="url(#d)" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="url(#d)" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="url(#d)" stroke="cyan" />
+ </pattern>
+
+ <pattern id="d" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#c)" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="url(#c)" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="url(#c)" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="url(#c)" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="url(#c)" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="url(#c)" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="url(#c)" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="url(#c)" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="url(#c)" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="url(#c)" stroke="cyan" />
+ </pattern>
+ <pattern id="c" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#b)" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="url(#b)" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="url(#b)" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="url(#b)" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="url(#b)" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="url(#b)" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="url(#b)" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="url(#b)" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="url(#b)" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="url(#b)" stroke="cyan" />
+ </pattern>
+ <pattern id="b" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="url(#a)" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="url(#a)" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="url(#a)" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="url(#a)" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="url(#a)" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="url(#a)" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="url(#a)" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="url(#a)" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="url(#a)" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="url(#a)" stroke="cyan" />
+
+ </pattern>
+ <pattern id="a" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(0.5,0.5)">
+ <rect x="0" y="0" width="20" height="20" fill="none" stroke="green" />
+ <rect x="1" y="1" width="20" height="20" fill="none" stroke="brown" />
+ <rect x="2" y="2" width="20" height="20" fill="none" stroke="pink" />
+ <rect x="3" y="3" width="20" height="20" fill="none" stroke="grey" />
+ <rect x="4" y="3" width="20" height="20" fill="none" stroke="cyan" />
+ <rect x="5" y="3" width="20" height="20" fill="none" stroke="green" />
+ <rect x="6" y="3" width="20" height="20" fill="none" stroke="brown" />
+ <rect x="7" y="3" width="20" height="20" fill="none" stroke="pink" />
+ <rect x="8" y="3" width="20" height="20" fill="none" stroke="grey" />
+ <rect x="9" y="3" width="20" height="20" fill="none" stroke="cyan" />
+ </pattern>
+ </defs>
+
+ <ellipse fill="url(#z)" stroke="black" stroke-width="5"
+ cx="400" cy="200" rx="350" ry="150" />
+
+</svg>
\ No newline at end of file
diff --git a/tests/fixtures/errors/515-too-many-elements.svgz b/tests/fixtures/errors/515-too-many-elements.svgz
new file mode 100644
index 0000000000000000000000000000000000000000..a7f7cf678ca2f29af6df61078d1c6a86c73c2d1a
GIT binary patch
literal 40811
zcmeIuO)I1U007{3c1mhf$VD-7q(+J1MDM}L%|UFTsL8?1JBN{yP&im}QQ{&|QhvZj
zljI=9MY%ail5kSH<)g@tkhY%ZCp<Na#l^QJoBcoHsm4@tG?z<e2cz+1I+M<(qtSdr
zerz~+JUc3x2`j>*LibxH_PE;`Ph^fuo4Xpr-qW6!wVUeOr_1r`p~-)LTcZB@uIs(k
zp^3xx{A%Lt>ENbsBzwPKxl_B*S@%4>{ZPBL{_?u~dmaM@3>YwAz<>b*1`HT5V8DO@
z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*Vq
ziwEvbqN?)X)ARdf*>V8`1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*
z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA;JXJdqN<A^m<@v0;iCA@vC?p6
zYVLd>)r0{91`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>f$?1`2;_+E#M0g<n@o
I9YGlT0Agk%tpET3
literal 0
HcmV?d00001
--
2.26.2

View File

@ -0,0 +1,81 @@
From 2346aa25ba6379db5a754f2cb7171e85cba5dda3 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Fri, 15 May 2020 14:56:59 -0500
Subject: [PATCH] cssparser build fix
---
vendor/cssparser/.cargo-checksum.json | 2 +-
vendor/cssparser/src/parser.rs | 48 +++++++++++++++------------
2 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/vendor/cssparser/.cargo-checksum.json b/vendor/cssparser/.cargo-checksum.json
index 246bb70..713372d 100644
--- a/vendor/cssparser/.cargo-checksum.json
+++ b/vendor/cssparser/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"f1fb4b65964c81bc1240544267ea334f554ca38ae7a74d57066f4d47d2b5d568","Cargo.toml":"7807f16d417eb1a6ede56cd4ba2da6c5c63e4530289b3f0848f4b154e18eba02","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"c5781e673335f37ed3d7acb119f8ed33efdf6eb75a7094b7da2abe0c3230adb8","build.rs":"b29fc57747f79914d1c2fb541e2bb15a003028bb62751dcb901081ccc174b119","build/match_byte.rs":"2c84b8ca5884347d2007f49aecbd85b4c7582085526e2704399817249996e19b","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","docs/index.html":"025861f76f8d1f6d67c20ab624c6e418f4f824385e2dd8ad8732c4ea563c6a2e","src/color.rs":"c60f1b0ab7a2a6213e434604ee33f78e7ef74347f325d86d0b9192d8225ae1cc","src/cow_rc_str.rs":"541216f8ef74ee3cc5cbbc1347e5f32ed66588c401851c9a7d68b867aede1de0","src/from_bytes.rs":"331fe63af2123ae3675b61928a69461b5ac77799fff3ce9978c55cf2c558f4ff","src/lib.rs":"46c377e0c9a75780d5cb0bcf4dfb960f0fb2a996a13e7349bb111b9082252233","src/macros.rs":"adb9773c157890381556ea83d7942dcc676f99eea71abbb6afeffee1e3f28960","src/nth.rs":"5c70fb542d1376cddab69922eeb4c05e4fcf8f413f27563a2af50f72a47c8f8c","src/parser.rs":"9ed4aec998221eb2d2ba99db2f9f82a02399fb0c3b8500627f68f5aab872adde","src/rules_and_declarations.rs":"be2c4f3f3bb673d866575b6cb6084f1879dff07356d583ca9a3595f63b7f916f","src/serializer.rs":"4ccfc9b4fe994aab3803662bbf31cc25052a6a39531073a867b14b224afe42dd","src/size_of_tests.rs":"e5f63c8c18721cc3ff7a5407e84f9889ffa10e66da96e8510a696c3e00ad72d5","src/tests.rs":"80b02c80ab0fd580dad9206615c918e0db7dff63dfed0feeedb66f317d24b24b","src/tokenizer.rs":"429b2cba419cf8b923fbcc32d3bd34c0b39284ebfcb9fc29b8eb8643d8d5f312","src/unicode_range.rs":"c1c4ed2493e09d248c526ce1ef8575a5f8258da3962b64ffc814ef3bdf9780d0"},"package":"8a807ac3ab7a217829c2a3b65732b926b2befe6a35f33b4bf8b503692430f223"}
\ No newline at end of file
+{"files":{},"package":"8a807ac3ab7a217829c2a3b65732b926b2befe6a35f33b4bf8b503692430f223"}
diff --git a/vendor/cssparser/src/parser.rs b/vendor/cssparser/src/parser.rs
index 76736a8..8ffa18c 100644
--- a/vendor/cssparser/src/parser.rs
+++ b/vendor/cssparser/src/parser.rs
@@ -555,28 +555,34 @@ impl<'i: 't, 't> Parser<'i, 't> {
}
let token_start_position = self.input.tokenizer.position();
- let token;
- match self.input.cached_token {
- Some(ref cached_token)
- if cached_token.start_position == token_start_position => {
- self.input.tokenizer.reset(&cached_token.end_state);
- match cached_token.token {
- Token::Function(ref name) => self.input.tokenizer.see_function(name),
- _ => {}
- }
- token = &cached_token.token
+ let using_cached_token = self
+ .input
+ .cached_token
+ .as_ref()
+ .map_or(false, |cached_token| {
+ cached_token.start_position == token_start_position
+ });
+ let token = if using_cached_token {
+ let cached_token = self.input.cached_token.as_ref().unwrap();
+ self.input.tokenizer.reset(&cached_token.end_state);
+ match cached_token.token {
+ Token::Function(ref name) => self.input.tokenizer.see_function(name),
+ _ => {}
}
- _ => {
- let new_token = self.input.tokenizer.next()
- .map_err(|()| self.new_basic_error(BasicParseErrorKind::EndOfInput))?;
- self.input.cached_token = Some(CachedToken {
- token: new_token,
- start_position: token_start_position,
- end_state: self.input.tokenizer.state(),
- });
- token = self.input.cached_token_ref()
- }
- }
+ &cached_token.token
+ } else {
+ let new_token = self
+ .input
+ .tokenizer
+ .next()
+ .map_err(|()| self.new_basic_error(BasicParseErrorKind::EndOfInput))?;
+ self.input.cached_token = Some(CachedToken {
+ token: new_token,
+ start_position: token_start_position,
+ end_state: self.input.tokenizer.state(),
+ });
+ self.input.cached_token_ref()
+ };
if let Some(block_type) = BlockType::opening(token) {
self.at_start_of = Some(block_type);
--
2.26.2

View File

@ -11,12 +11,18 @@
Name: librsvg2
Summary: An SVG library based on cairo
Version: 2.42.7
Release: 3%{?dist}
Release: 4%{?dist}
License: LGPLv2+
URL: https://wiki.gnome.org/Projects/LibRsvg
Source0: https://download.gnome.org/sources/librsvg/2.42/librsvg-%{version}.tar.xz
# https://bugzilla.redhat.com/show_bug.cgi?id=1804519
# https://gitlab.gnome.org/GNOME/librsvg/-/issues/515
Patch0: CVE-2019-20446.patch
# https://github.com/servo/rust-cssparser/pull/245
Patch1: fix-cssparser-build.patch
BuildRequires: chrpath
BuildRequires: gcc
BuildRequires: gobject-introspection-devel
@ -75,7 +81,7 @@ Requires: %{name}%{?_isa} = %{version}-%{release}
This package provides extra utilities based on the librsvg library.
%prep
%autosetup -n librsvg-%{version} -p1
%autosetup -n librsvg-%{version} -p1 -S git
%if 0%{?bundled_rust_deps}
# Use the bundled deps, and enable release debuginfo
sed -i -e '/profile.release/a debug = true' Cargo.toml
@ -133,6 +139,9 @@ rm -vrf %{buildroot}%{_datadir}/doc
%{_mandir}/man1/rsvg-convert.1*
%changelog
* Wed May 13 2020 Michael Catanzaro <mcatanzaro@redhat.com> - 2.42.7-4
- Resolves: rhbz#1804519 Add patch for CVE-2019-20446
* Thu Dec 06 2018 Josh Stone <jistone@redhat.com> - 2.42.7-2
- Rebuild with the current rust-toolset