[librsvg/librsvg-2.44: 3/7] Keep track of the number of referenced nodes



commit d8e265b3a293a650399a1d4eb85d749596c10055
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Feb 26 17:31:02 2020 -0600

    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 {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]