[librsvg/librsvg-2.46] AcquiredNodes: Only push nodes which are accessed by reference
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.46] AcquiredNodes: Only push nodes which are accessed by reference
- Date: Tue, 15 Oct 2019 16:47:48 +0000 (UTC)
commit cfb84808e783954f281fde51a62d27e5ecde8db7
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Oct 15 08:46:05 2019 -0500
AcquiredNodes: Only push nodes which are accessed by reference
"Indirect" nodes like pattern, linearGradient, etc. are the ones
normally only used through a reference from a fill="url(#...)",
filter="url(#...)", etc. These indirect nodes, can cause "direct"
nodes to be referenced, which can in turn reference other indirect
nodes, thus causing a potential reference cycle.
We now only push indirect nodes into the stack of acquired nodes -
that is, only nodes that are only used by reference.
Direct nodes like <use> which always cause other nodes to be
referenced will have to add themselves to the stack, as in upcoming
commits.
rsvg_internals/src/drawing_ctx.rs | 41 +++++++++++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 8 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index cc22d43e..589ed501 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -1138,19 +1138,44 @@ impl AcquiredNodes {
) -> Result<AcquiredNode, AcquireError> {
let node = self.lookup_node(fragment, node_types)?;
- if self.node_stack.borrow().contains(&node) {
- Err(AcquireError::CircularReference(fragment.clone()))
+ if node_is_accessed_by_reference(&node) {
+ if self.node_stack.borrow().contains(&node) {
+ Err(AcquireError::CircularReference(fragment.clone()))
+ } else {
+ self.node_stack.borrow_mut().push(&node);
+ Ok(AcquiredNode {
+ stack: Some(self.node_stack.clone()),
+ node: node.clone()
+ })
+ }
} else {
- self.node_stack.borrow_mut().push(&node);
- let acquired = AcquiredNode {
- stack: Some(self.node_stack.clone()),
- node: node.clone()
- };
- Ok(acquired)
+ Ok(AcquiredNode {
+ stack: None,
+ node: node.clone(),
+ })
}
}
}
+// Returns whether a node of a particular type is only accessed by reference
+// from other nodes' atributes. The node could in turn cause other nodes
+// to get referenced, potentially causing reference cycles.
+fn node_is_accessed_by_reference(node: &RsvgNode) -> bool {
+ use NodeType::*;
+
+ match node.borrow().get_type() {
+ ClipPath |
+ Filter |
+ LinearGradient |
+ Marker |
+ Mask |
+ Pattern |
+ RadialGradient => true,
+
+ _ => false,
+ }
+}
+
/// Keeps a stack of nodes and can check if a certain node is contained in the stack
///
/// Sometimes parts of the code cannot plainly use the implicit stack of acquired
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]