pub struct AcquiredNodes<'i> {
    document: &'i Document,
    num_elements_acquired: usize,
    node_stack: Rc<RefCell<NodeStack>>,
}
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>>

Implementations§

source§

impl<'i> AcquiredNodes<'i>

source

pub fn new(document: &Document) -> AcquiredNodes<'_>

source

pub fn lookup_image( &self, href: &str ) -> Result<SharedImageSurface, LoadingError>

source

pub fn lookup_resource(&self, url: &str) -> Result<Resource, LoadingError>

source

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 ids are being resolved to node references.

source

pub fn acquire_ref( &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 its Node 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> !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> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.