On 22/07/2020 13:19, Emilio Pozuelo Monfort wrote:
> So I have gone with the minimal backport to 2.44.10 instead (which I've
> also tested) and it's already uploaded. debdiff attached.

Attached for real now.

Emilio
diff -Nru librsvg-2.44.10/debian/changelog librsvg-2.44.10/debian/changelog
--- librsvg-2.44.10/debian/changelog    2019-04-25 21:55:18.000000000 +0200
+++ librsvg-2.44.10/debian/changelog    2020-07-22 13:11:57.000000000 +0200
@@ -1,3 +1,9 @@
+librsvg (2.44.10-2.1+deb10u1) buster; urgency=medium
+
+  * CVE-2019-20446: DoS via billion laughs attack.
+
+ -- Emilio Pozuelo Monfort <po...@debian.org>  Wed, 22 Jul 2020 13:11:57 +0200
+
 librsvg (2.44.10-2.1) unstable; urgency=high
 
   * Non-maintainer upload.
diff -Nru 
librsvg-2.44.10/debian/patches/0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch
 
librsvg-2.44.10/debian/patches/0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch
--- 
librsvg-2.44.10/debian/patches/0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
librsvg-2.44.10/debian/patches/0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch
      2020-07-11 20:11:58.000000000 +0200
@@ -0,0 +1,79 @@
+From c5738c7716f66e66ba23aa169e79eb478b7804c5 Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <feder...@gnome.org>
+Date: Thu, 10 Oct 2019 15:16:19 -0500
+Subject: [PATCH 1/5] limits.rs - New file; move the constant for maximum
+ instanced nodes here
+
+---
+ Makefile.am                       |  1 +
+ rsvg_internals/src/drawing_ctx.rs |  3 ++-
+ rsvg_internals/src/lib.rs         |  1 +
+ rsvg_internals/src/limits.rs      | 11 +++++++++++
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+ create mode 100644 rsvg_internals/src/limits.rs
+
+diff --git a/Makefile.am b/Makefile.am
+index e075c958..bb181dc2 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -81,6 +81,7 @@ RUST_SRC =                                                   
\
+       rsvg_internals/src/iri.rs                               \
+       rsvg_internals/src/length.rs                            \
+       rsvg_internals/src/lib.rs                               \
++      rsvg_internals/src/limits.rs                            \
+       rsvg_internals/src/log.rs                               \
+       rsvg_internals/src/link.rs                              \
+       rsvg_internals/src/load.rs                              \
+diff --git a/rsvg_internals/src/drawing_ctx.rs 
b/rsvg_internals/src/drawing_ctx.rs
+index 9bf9d295..c9c2d169 100644
+--- a/rsvg_internals/src/drawing_ctx.rs
++++ b/rsvg_internals/src/drawing_ctx.rs
+@@ -19,6 +19,7 @@ use error::RenderingError;
+ use filters;
+ use float_eq_cairo::ApproxEqCairo;
+ use length::Dasharray;
++use limits;
+ use mask::NodeMask;
+ use node::{CascadedValues, NodeType, RsvgNode};
+ use paint_server::{self, PaintServer};
+@@ -863,7 +864,7 @@ impl<'a> DrawingCtx<'a> {
+     }
+ 
+     fn check_limits(&self) -> Result<(), RenderingError> {
+-        if self.num_elements_rendered_through_use > 500_000 {
++        if self.num_elements_rendered_through_use > 
limits::MAX_REFERENCED_ELEMENTS {
+             Err(RenderingError::InstancingLimit)
+         } else {
+             Ok(())
+diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
+index 1d36d394..99704df4 100644
+--- a/rsvg_internals/src/lib.rs
++++ b/rsvg_internals/src/lib.rs
+@@ -113,6 +113,7 @@ mod handle;
+ mod image;
+ mod iri;
+ mod length;
++mod limits;
+ mod link;
+ mod load;
+ mod marker;
+diff --git a/rsvg_internals/src/limits.rs b/rsvg_internals/src/limits.rs
+new file mode 100644
+index 00000000..f5d58d95
+--- /dev/null
++++ b/rsvg_internals/src/limits.rs
+@@ -0,0 +1,11 @@
++/// This is a mitigation for the security-related bug
++/// https://gitlab.gnome.org/GNOME/librsvg/issues/323 - imagine
++/// the XML [billion laughs attack], but done by creating 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.
++///
++/// [billion laughs attack]: https://bitbucket.org/tiran/defusedxml
++pub const MAX_REFERENCED_ELEMENTS: usize = 500_000;
+-- 
+2.20.1
+
diff -Nru 
librsvg-2.44.10/debian/patches/0002-Rename-num_elements_rendered_through_use-to-num_elem.patch
 
librsvg-2.44.10/debian/patches/0002-Rename-num_elements_rendered_through_use-to-num_elem.patch
--- 
librsvg-2.44.10/debian/patches/0002-Rename-num_elements_rendered_through_use-to-num_elem.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
librsvg-2.44.10/debian/patches/0002-Rename-num_elements_rendered_through_use-to-num_elem.patch
      2020-07-11 20:11:58.000000000 +0200
@@ -0,0 +1,66 @@
+From 1b63d474943e8f1fe77757ee87f2d39502e32fda Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <feder...@gnome.org>
+Date: Thu, 10 Oct 2019 15:26:14 -0500
+Subject: [PATCH 2/5] Rename num_elements_rendered_through_use to
+ num_elements_acquired
+
+We'll change this to be the number of elements ever acquired through
+DrawingCtx.acquire_node(), instead of just those being instanced
+through the <use> element.  It turns out one can create a pathological
+SVG file that causes an exponential number of elements to be rendered,
+without using <use>.
+---
+ rsvg_internals/src/drawing_ctx.rs | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/rsvg_internals/src/drawing_ctx.rs 
b/rsvg_internals/src/drawing_ctx.rs
+index c9c2d169..0d0e401b 100644
+--- a/rsvg_internals/src/drawing_ctx.rs
++++ b/rsvg_internals/src/drawing_ctx.rs
+@@ -101,17 +101,9 @@ pub struct DrawingCtx<'a> {
+     dpi_x: f64,
+     dpi_y: f64,
+ 
+-    /// This is a mitigation for the security-related bug
+-    /// https://gitlab.gnome.org/GNOME/librsvg/issues/323 - imagine
+-    /// the XML [billion laughs attack], but done by creating 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.
+-    ///
+-    /// [billion laughs attack]: https://bitbucket.org/tiran/defusedxml
+-    num_elements_rendered_through_use: usize,
++    // This is a mitigation for SVG files that try to instance a huge number 
of
++    // elements via <use>, recursive patterns, etc.  See limits.rs for 
details.
++    num_elements_acquired: usize,
+ 
+     cr_stack: Vec<cairo::Context>,
+     cr: cairo::Context,
+@@ -170,7 +162,7 @@ impl<'a> DrawingCtx<'a> {
+             rect,
+             dpi_x,
+             dpi_y,
+-            num_elements_rendered_through_use: 0,
++            num_elements_acquired: 0,
+             cr_stack: Vec::new(),
+             cr: cr.clone(),
+             initial_cr: cr.clone(),
+@@ -860,11 +852,11 @@ impl<'a> DrawingCtx<'a> {
+     }
+ 
+     pub fn increase_num_elements_rendered_through_use(&mut self, n: usize) {
+-        self.num_elements_rendered_through_use += n;
++        self.num_elements_acquired += n;
+     }
+ 
+     fn check_limits(&self) -> Result<(), RenderingError> {
+-        if self.num_elements_rendered_through_use > 
limits::MAX_REFERENCED_ELEMENTS {
++        if self.num_elements_acquired > limits::MAX_REFERENCED_ELEMENTS {
+             Err(RenderingError::InstancingLimit)
+         } else {
+             Ok(())
+-- 
+2.20.1
+
diff -Nru 
librsvg-2.44.10/debian/patches/0003-Keep-track-of-the-number-of-referenced-nodes.patch
 
librsvg-2.44.10/debian/patches/0003-Keep-track-of-the-number-of-referenced-nodes.patch
--- 
librsvg-2.44.10/debian/patches/0003-Keep-track-of-the-number-of-referenced-nodes.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
librsvg-2.44.10/debian/patches/0003-Keep-track-of-the-number-of-referenced-nodes.patch
      2020-07-11 20:11:58.000000000 +0200
@@ -0,0 +1,75 @@
+From d8e265b3a293a650399a1d4eb85d749596c10055 Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <feder...@gnome.org>
+Date: Wed, 26 Feb 2020 17:31:02 -0600
+Subject: [PATCH 3/5] Keep track of the number of referenced nodes
+
+---
+ rsvg_internals/src/drawing_ctx.rs | 30 ++++++++++++++++++++++--------
+ rsvg_internals/src/error.rs       |  1 +
+ 2 files changed, 23 insertions(+), 8 deletions(-)
+
+diff --git a/rsvg_internals/src/drawing_ctx.rs 
b/rsvg_internals/src/drawing_ctx.rs
+index 0d0e401b..6dfadc8e 100644
+--- a/rsvg_internals/src/drawing_ctx.rs
++++ b/rsvg_internals/src/drawing_ctx.rs
+@@ -275,15 +275,29 @@ impl<'a> DrawingCtx<'a> {
+     // acquire it again.  If you acquire a node "#foo" and don't release it 
before
+     // trying to acquire "foo" again, you will obtain a %NULL the second time.
+     pub fn get_acquired_node(&mut self, url: &str) -> Option<AcquiredNode> {
+-        if let Some(node) = self.defs.borrow_mut().lookup(url) {
+-            if !self.acquired_nodes_contains(node) {
+-                self.acquired_nodes.borrow_mut().push(node.clone());
+-                let acq = AcquiredNode(self.acquired_nodes.clone(), 
node.clone());
+-                return Some(acq);
+-            }
++        self.num_elements_acquired += 1;
++
++        if self.num_elements_acquired > limits::MAX_REFERENCED_ELEMENTS {
++            return None;
++        }
++
++        let mut defs_mut = self.defs.borrow_mut();
++
++        if let Some(node) = defs_mut.lookup(url) {
++            self.acquire_node_ref(node)
++        } else {
++            None
+         }
++    }
+ 
+-        None
++    pub fn acquire_node_ref(&self, node: &RsvgNode) -> Option<AcquiredNode> {
++        if !self.acquired_nodes_contains(node) {
++            self.acquired_nodes.borrow_mut().push(node.clone());
++            let acq = AcquiredNode(self.acquired_nodes.clone(), node.clone());
++            Some(acq)
++        } else {
++            None
++        }
+     }
+ 
+     fn acquired_nodes_contains(&self, node: &RsvgNode) -> bool {
+@@ -857,7 +871,7 @@ impl<'a> DrawingCtx<'a> {
+ 
+     fn check_limits(&self) -> Result<(), RenderingError> {
+         if self.num_elements_acquired > limits::MAX_REFERENCED_ELEMENTS {
+-            Err(RenderingError::InstancingLimit)
++            Err(RenderingError::MaxReferencesExceeded)
+         } else {
+             Ok(())
+         }
+diff --git a/rsvg_internals/src/error.rs b/rsvg_internals/src/error.rs
+index df0d9b9d..6d853505 100644
+--- a/rsvg_internals/src/error.rs
++++ b/rsvg_internals/src/error.rs
+@@ -91,6 +91,7 @@ pub enum RenderingError {
+     Cairo(cairo::Status),
+     CircularReference,
+     InstancingLimit,
++    MaxReferencesExceeded,
+ }
+ 
+ impl From<cairo::Status> for RenderingError {
+-- 
+2.20.1
+
diff -Nru 
librsvg-2.44.10/debian/patches/0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch
 
librsvg-2.44.10/debian/patches/0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch
--- 
librsvg-2.44.10/debian/patches/0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
librsvg-2.44.10/debian/patches/0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch
      2020-07-11 20:11:58.000000000 +0200
@@ -0,0 +1,331 @@
+From 9f3432763bfe42f91415abb45bdcc89e0c8a355c Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <feder...@gnome.org>
+Date: Wed, 26 Feb 2020 17:46:05 -0600
+Subject: [PATCH 4/5] NodeUse: fix infinite loops due to recursive references
+ of "use" elements
+
+---
+ rsvg_internals/src/drawing_ctx.rs             |   4 -
+ rsvg_internals/src/structure.rs               |  19 ++-
+ tests/errors.c                                |  42 +++++-
+ .../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 ++++++++++++++++++
+ 7 files changed, 207 insertions(+), 17 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
+
+diff --git a/rsvg_internals/src/drawing_ctx.rs 
b/rsvg_internals/src/drawing_ctx.rs
+index 6dfadc8e..890b1ac2 100644
+--- a/rsvg_internals/src/drawing_ctx.rs
++++ b/rsvg_internals/src/drawing_ctx.rs
+@@ -865,10 +865,6 @@ impl<'a> DrawingCtx<'a> {
+         }
+     }
+ 
+-    pub fn increase_num_elements_rendered_through_use(&mut self, n: usize) {
+-        self.num_elements_acquired += n;
+-    }
+-
+     fn check_limits(&self) -> Result<(), RenderingError> {
+         if self.num_elements_acquired > limits::MAX_REFERENCED_ELEMENTS {
+             Err(RenderingError::MaxReferencesExceeded)
+diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
+index f384413e..b7e53ce2 100644
+--- a/rsvg_internals/src/structure.rs
++++ b/rsvg_internals/src/structure.rs
+@@ -297,6 +297,18 @@ impl NodeTrait for NodeUse {
+ 
+         let uri = link.as_ref().unwrap();
+ 
++        // <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_acquired = draw_ctx.acquire_node_ref(node);
++        if self_acquired.is_none() {
++            return Err(RenderingError::CircularReference);
++        }
++
+         let child = if let Some(acquired) = draw_ctx.get_acquired_node(uri) {
+             // Here we clone the acquired child, so that we can drop the 
AcquiredNode as
+             // early as possible.  This is so that the child's drawing method 
will be able
+@@ -311,13 +323,6 @@ impl NodeTrait for NodeUse {
+             return Ok(());
+         };
+ 
+-        if Node::is_ancestor(child.clone(), node.clone()) {
+-            // or, if we're <use>'ing ourselves
+-            return Err(RenderingError::CircularReference);
+-        }
+-
+-        draw_ctx.increase_num_elements_rendered_through_use(1);
+-
+         let params = draw_ctx.get_view_params();
+ 
+         let nx = self.x.get().normalize(values, &params);
+diff --git a/tests/errors.c b/tests/errors.c
+index bdf6db7b..85663004 100644
+--- a/tests/errors.c
++++ b/tests/errors.c
+@@ -24,9 +24,10 @@ get_test_filename (const char *basename) {
+ }
+ 
+ static void
+-test_non_svg_element (void)
++test_loading_error (gconstpointer data)
+ {
+-    char *filename = get_test_filename ("335-non-svg-element.svg");
++    const char *basename = data;
++    char *filename = get_test_filename (basename);
+     RsvgHandle *handle;
+     GError *error = NULL;
+ 
+@@ -35,12 +36,15 @@ test_non_svg_element (void)
+ 
+     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;
+@@ -64,8 +68,34 @@ main (int argc, char **argv)
+ {
+     g_test_init (&argc, &argv, NULL);
+ 
+-    g_test_add_func ("/errors/non_svg_element", test_non_svg_element);
+-    g_test_add_func ("/errors/instancing_limit", test_instancing_limit);
++    g_test_add_data_func_full ("/errors/non_svg_element",
++                               "335-non-svg-element.svg",
++                               test_loading_error,
++                               NULL);
++
++    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);
++
+ 
+     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 00000000..9b248a6f
+--- /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 00000000..f5d00bf2
+--- /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 00000000..dbf14c54
+--- /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 00000000..1cb6cbe8
+--- /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
+-- 
+2.20.1
+
diff -Nru 
librsvg-2.44.10/debian/patches/0005-Limit-the-number-of-loaded-elements.patch 
librsvg-2.44.10/debian/patches/0005-Limit-the-number-of-loaded-elements.patch
--- 
librsvg-2.44.10/debian/patches/0005-Limit-the-number-of-loaded-elements.patch   
    1970-01-01 01:00:00.000000000 +0100
+++ 
librsvg-2.44.10/debian/patches/0005-Limit-the-number-of-loaded-elements.patch   
    2020-07-11 20:17:33.000000000 +0200
@@ -0,0 +1,75 @@
+From 5edea8ca9fbecbd6c36f7fd28894e49f356d8b78 Mon Sep 17 00:00:00 2001
+From: Federico Mena Quintero <feder...@gnome.org>
+Date: Wed, 26 Feb 2020 19:06:56 -0600
+Subject: [PATCH 5/5] Limit the number of loaded elements
+
+---
+ librsvg/rsvg-load.c                           |  20 ++++++++++++++++++
+ tests/errors.c                                |   4 ++++
+ .../errors/515-too-many-elements.svgz         | Bin 0 -> 40811 bytes
+ 3 files changed, 24 insertions(+)
+ create mode 100644 tests/fixtures/errors/515-too-many-elements.svgz
+
+diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
+index 44e1f670..ea1e2bfb 100644
+--- a/librsvg/rsvg-load.c
++++ b/librsvg/rsvg-load.c
+@@ -66,6 +66,7 @@ struct RsvgLoad {
+      */
+     RsvgSaxHandler *handler;
+     int handler_nest;
++    gsize num_loaded_elements;
+ 
+     GHashTable *entities;       /* g_malloc'd string -> xmlEntityPtr */
+ 
+@@ -608,12 +609,31 @@ start_xinclude (RsvgLoad *load, RsvgPropertyBag * atts)
+ 
+ /* end xinclude */
+ 
++static gboolean
++loading_limits_exceeded (RsvgLoad *load)
++{
++    /* 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 load->num_loaded_elements > 200000;
++}
++
+ static void
+ sax_start_element_cb (void *data, const xmlChar * name, const xmlChar ** atts)
+ {
+     RsvgPropertyBag bag;
+     RsvgLoad *load = data;
+ 
++    if (loading_limits_exceeded (load)) {
++        g_set_error (load->error, RSVG_ERROR, 0, "instancing limit");
++
++        xmlStopParser (load->ctxt);
++        return;
++    }
++
++    load->num_loaded_elements += 1;
++
+     bag = rsvg_property_bag_new ((const char **) atts);
+ 
+     if (load->handler) {
+diff --git a/tests/errors.c b/tests/errors.c
+index 85663004..52795680 100644
+--- a/tests/errors.c
++++ b/tests/errors.c
+@@ -96,6 +96,10 @@ main (int argc, char **argv)
+                                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 ();
+ }
+
+-- 
+2.20.1
+
diff -Nru librsvg-2.44.10/debian/patches/series 
librsvg-2.44.10/debian/patches/series
--- librsvg-2.44.10/debian/patches/series       2019-04-25 21:54:21.000000000 
+0200
+++ librsvg-2.44.10/debian/patches/series       2020-07-11 20:12:17.000000000 
+0200
@@ -2,3 +2,8 @@
 typenum-i386-ftbfs.patch
 i386-rounding-errors.patch
 keep-positive-radii.patch
+0001-limits.rs-New-file-move-the-constant-for-maximum-ins.patch
+0002-Rename-num_elements_rendered_through_use-to-num_elem.patch
+0003-Keep-track-of-the-number-of-referenced-nodes.patch
+0004-NodeUse-fix-infinite-loops-due-to-recursive-referenc.patch
+0005-Limit-the-number-of-loaded-elements.patch
diff -Nru librsvg-2.44.10/debian/source/include-binaries 
librsvg-2.44.10/debian/source/include-binaries
--- librsvg-2.44.10/debian/source/include-binaries      1970-01-01 
01:00:00.000000000 +0100
+++ librsvg-2.44.10/debian/source/include-binaries      2020-07-11 
20:20:12.000000000 +0200
@@ -0,0 +1 @@
+tests/fixtures/errors/515-too-many-elements.svgz
Binary files 
/tmp/dtBncWIUMD/librsvg-2.44.10/tests/fixtures/errors/515-too-many-elements.svgz
 and 
/tmp/pPLtG7c90L/librsvg-2.44.10/tests/fixtures/errors/515-too-many-elements.svgz
 differ

Reply via email to