Struct rsvg::document::AcquiredNodes
source · pub struct AcquiredNodes<'i> {
document: &'i Document,
num_elements_acquired: usize,
node_stack: Rc<RefCell<NodeStack>>,
nodes_with_cycles: Vec<Node<NodeData>>,
cancellable: Option<Cancellable>,
}
Expand description
Detects circular references between nodes, and enforces referencing limits.
Consider this fragment of SVG:
<pattern id="foo">
<rect width="1" height="1" fill="url(#foo)"/>
</pattern>
The pattern has a child element that references the pattern itself. This kind of circular
reference is invalid. The AcquiredNodes
struct is passed around
wherever it may be necessary to resolve references to nodes, or to access nodes
“elsewhere” in the DOM that is not the current subtree.
Also, such constructs that reference other elements can be maliciously arranged like
in the billion laughs attack, to cause huge amounts of CPU to be consumed through
creating an exponential number of references. AcquiredNodes
imposes a hard limit on
the number of references that can be resolved for typical, well-behaved SVG documents.
The Self::acquire()
and Self::acquire_ref()
methods return an AcquiredNode
, which
acts like a smart pointer for a Node
. Once a node has been acquired, it cannot be
acquired again until its AcquiredNode
is dropped. In the example above, a graphic element
would acquire the pattern
, which would then acquire its rect
child, which then would fail
to re-acquired the pattern
— thus signaling a circular reference.
Those methods return an AcquireError
to signal circular references. Also, they
can return AcquireError::MaxReferencesExceeded
if the aforementioned referencing limit
is exceeded.
Fields§
§document: &'i Document
§num_elements_acquired: usize
§node_stack: Rc<RefCell<NodeStack>>
§nodes_with_cycles: Vec<Node<NodeData>>
§cancellable: Option<Cancellable>
Implementations§
source§impl<'i> AcquiredNodes<'i>
impl<'i> AcquiredNodes<'i>
pub fn new( document: &Document, cancellable: Option<Cancellable>, ) -> AcquiredNodes<'_>
pub fn lookup_resource(&self, url: &str) -> Result<Resource, LoadingError>
sourcepub fn acquire(
&mut self,
node_id: &NodeId,
) -> Result<AcquiredNode, AcquireError>
pub fn acquire( &mut self, node_id: &NodeId, ) -> Result<AcquiredNode, AcquireError>
Acquires a node by its id.
This is typically used during an “early resolution” stage, when XML id
s are being
resolved to node references.
sourcepub fn acquire_ref(
&mut self,
node: &Node<NodeData>,
) -> Result<AcquiredNode, AcquireError>
pub fn acquire_ref( &mut self, node: &Node<NodeData>, ) -> Result<AcquiredNode, AcquireError>
Acquires a node whose reference is already known.
This is useful for cases where a node is initially referenced by its id with
Self::acquire
and kept around for later use. During the later use, the node
needs to be re-acquired with this method. For example:
-
At an “early resolution” stage,
acquire()
a pattern by its id, and keep around itsNode
reference. -
At the drawing stage,
acquire_ref()
the pattern node that we already had, so that its child elements that reference other paint servers will be able to detect circular references to the pattern.
Auto Trait Implementations§
impl<'i> Freeze for AcquiredNodes<'i>
impl<'i> !RefUnwindSafe for AcquiredNodes<'i>
impl<'i> !Send for AcquiredNodes<'i>
impl<'i> !Sync for AcquiredNodes<'i>
impl<'i> Unpin for AcquiredNodes<'i>
impl<'i> !UnwindSafe for AcquiredNodes<'i>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> Pointable for T
impl<T> Pointable for T
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.