Skip to content

Commit 9f65158

Browse files
federicomenaquinteroMarge Bot
authored andcommitted
AcquiredNodes: keep a list of nodes known to be part of reference cycles
Throughout the rendering process, we'll find the cycles and keep them around; this lets us catch them as soon as they are accessed later. Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/988>
1 parent 939ab51 commit 9f65158

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

rsvg/src/document.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ pub struct AcquiredNodes<'i> {
766766
document: &'i Document,
767767
num_elements_acquired: usize,
768768
node_stack: Rc<RefCell<NodeStack>>,
769+
nodes_with_cycles: Vec<Node>,
769770
}
770771

771772
impl<'i> AcquiredNodes<'i> {
@@ -774,6 +775,7 @@ impl<'i> AcquiredNodes<'i> {
774775
document,
775776
num_elements_acquired: 0,
776777
node_stack: Rc::new(RefCell::new(NodeStack::new())),
778+
nodes_with_cycles: Vec::new(),
777779
}
778780
}
779781

@@ -810,6 +812,10 @@ impl<'i> AcquiredNodes<'i> {
810812
.lookup_node(node_id)
811813
.ok_or_else(|| AcquireError::LinkNotFound(node_id.clone()))?;
812814

815+
if self.nodes_with_cycles.contains(&node) {
816+
return Err(AcquireError::CircularReference(node.clone()));
817+
}
818+
813819
if node.borrow_element().is_accessed_by_reference() {
814820
self.acquire_ref(&node)
815821
} else {
@@ -829,8 +835,11 @@ impl<'i> AcquiredNodes<'i> {
829835
/// * At the drawing stage, `acquire_ref()` the pattern node that we already had, so that
830836
/// its child elements that reference other paint servers will be able to detect circular
831837
/// references to the pattern.
832-
pub fn acquire_ref(&self, node: &Node) -> Result<AcquiredNode, AcquireError> {
833-
if self.node_stack.borrow().contains(node) {
838+
pub fn acquire_ref(&mut self, node: &Node) -> Result<AcquiredNode, AcquireError> {
839+
if self.nodes_with_cycles.contains(node) {
840+
Err(AcquireError::CircularReference(node.clone()))
841+
} else if self.node_stack.borrow().contains(node) {
842+
self.nodes_with_cycles.push(node.clone());
834843
Err(AcquireError::CircularReference(node.clone()))
835844
} else {
836845
self.node_stack.borrow_mut().push(node);

0 commit comments

Comments
 (0)