Skip to main content

quick_xml/
name.rs

1//! Module for handling names according to the W3C [Namespaces in XML 1.1 (Second Edition)][spec]
2//! specification
3//!
4//! [spec]: https://www.w3.org/TR/xml-names11
5
6use crate::events::attributes::Attribute;
7use crate::events::{BytesStart, Event};
8use std::fmt::{self, Debug, Formatter};
9use std::iter::FusedIterator;
10
11/// Some namespace was invalid
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum NamespaceError {
14    /// Specified namespace prefix is unknown, cannot resolve namespace for it
15    UnknownPrefix(String),
16    /// Attempts to bind the `xml` prefix to something other than `http://www.w3.org/XML/1998/namespace`.
17    ///
18    /// `xml` prefix can be bound only to `http://www.w3.org/XML/1998/namespace`.
19    ///
20    /// Contains the namespace to which `xml` tried to be bound.
21    InvalidXmlPrefixBind(String),
22    /// Attempts to bind the `xmlns` prefix.
23    ///
24    /// `xmlns` prefix is always bound to `http://www.w3.org/2000/xmlns/` and cannot be bound
25    /// to any other namespace or even to `http://www.w3.org/2000/xmlns/`.
26    ///
27    /// Contains the namespace to which `xmlns` tried to be bound.
28    InvalidXmlnsPrefixBind(String),
29    /// Attempts to bind some prefix (except `xml`) to `http://www.w3.org/XML/1998/namespace`.
30    ///
31    /// Only `xml` prefix can be bound to `http://www.w3.org/XML/1998/namespace`.
32    ///
33    /// Contains the prefix that is tried to be bound.
34    InvalidPrefixForXml(String),
35    /// Attempts to bind some prefix to `http://www.w3.org/2000/xmlns/`.
36    ///
37    /// `http://www.w3.org/2000/xmlns/` cannot be bound to any prefix, even to `xmlns`.
38    ///
39    /// Contains the prefix that is tried to be bound.
40    InvalidPrefixForXmlns(String),
41    /// The total number of `xmlns` / `xmlns:*` namespace bindings in scope exceeded
42    /// the configured [`NamespaceResolver::max_namespace_bindings`] limit. Contains
43    /// the configured limit.
44    ///
45    /// This bounds the work done by [`NamespaceResolver`] (and hence by [`NsReader`](crate::reader::NsReader))
46    /// on untrusted input by capping both the heap allocated and the cost of prefix
47    /// resolution (which scans the binding stack).
48    TooManyBindings(usize),
49    /// The document nested elements more deeply than the namespace resolver's
50    /// depth counter (a `u16`) can track. This bounds stack / scope-bookkeeping
51    /// work on untrusted input. Contains the depth limit that was exceeded.
52    TooDeeplyNested(usize),
53}
54
55impl fmt::Display for NamespaceError {
56    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57        match self {
58            Self::UnknownPrefix(prefix) => {
59                write!(f, "unknown namespace prefix '{}'", prefix)
60            }
61            Self::InvalidXmlPrefixBind(namespace) => {
62                write!(
63                    f,
64                    "the namespace prefix 'xml' cannot be bound to '{}'",
65                    namespace
66                )
67            }
68            Self::InvalidXmlnsPrefixBind(namespace) => {
69                write!(
70                    f,
71                    "the namespace prefix 'xmlns' cannot be bound to '{}'",
72                    namespace
73                )
74            }
75            Self::InvalidPrefixForXml(prefix) => {
76                write!(
77                    f,
78                    "the namespace prefix '{}' cannot be bound to 'http://www.w3.org/XML/1998/namespace'",
79                    prefix
80                )
81            }
82            Self::InvalidPrefixForXmlns(prefix) => {
83                write!(
84                    f,
85                    "the namespace prefix '{}' cannot be bound to 'http://www.w3.org/2000/xmlns/'",
86                    prefix
87                )
88            }
89            Self::TooManyBindings(limit) => {
90                write!(
91                    f,
92                    "more than {} namespace bindings in scope; \
93                     raise the limit with NamespaceResolver::set_max_namespace_bindings",
94                    limit,
95                )
96            }
97            Self::TooDeeplyNested(limit) => {
98                write!(
99                    f,
100                    "document nests elements deeper than the supported limit of {}",
101                    limit
102                )
103            }
104        }
105    }
106}
107
108impl std::error::Error for NamespaceError {}
109
110////////////////////////////////////////////////////////////////////////////////////////////////////
111
112/// A [qualified name] of an element or an attribute, including an optional
113/// namespace [prefix](Prefix) and a [local name](LocalName).
114///
115/// [qualified name]: https://www.w3.org/TR/xml-names11/#dt-qualname
116#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
117#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
118pub struct QName<'a>(pub &'a str);
119impl<'a> QName<'a> {
120    /// Converts this name to an internal slice representation.
121    #[inline(always)]
122    pub const fn into_inner(self) -> &'a str {
123        self.0
124    }
125
126    /// Returns local part of this qualified name.
127    ///
128    /// All content up to and including the first `:` character is removed from
129    /// the tag name.
130    ///
131    /// # Examples
132    ///
133    /// ```
134    /// # use quick_xml::name::QName;
135    /// let simple = QName("simple-name");
136    /// assert_eq!(simple.local_name().into_inner(), "simple-name");
137    ///
138    /// let qname = QName("namespace:simple-name");
139    /// assert_eq!(qname.local_name().into_inner(), "simple-name");
140    /// ```
141    pub fn local_name(&self) -> LocalName<'a> {
142        LocalName(self.index().map_or(self.0, |i| &self.0[i + 1..]))
143    }
144
145    /// Returns namespace part of this qualified name or `None` if namespace part
146    /// is not defined (symbol `':'` not found).
147    ///
148    /// # Examples
149    ///
150    /// ```
151    /// # use std::convert::AsRef;
152    /// # use quick_xml::name::QName;
153    /// let simple = QName("simple-name");
154    /// assert_eq!(simple.prefix(), None);
155    ///
156    /// let qname = QName("prefix:simple-name");
157    /// assert_eq!(qname.prefix().map(|n| n.into_inner()), Some("prefix"));
158    /// ```
159    pub fn prefix(&self) -> Option<Prefix<'a>> {
160        self.index().map(|i| Prefix(&self.0[..i]))
161    }
162
163    /// The same as `(qname.local_name(), qname.prefix())`, but does only one
164    /// lookup for a `':'` symbol.
165    pub fn decompose(&self) -> (LocalName<'a>, Option<Prefix<'a>>) {
166        match self.index() {
167            None => (LocalName(self.0), None),
168            Some(i) => (LocalName(&self.0[i + 1..]), Some(Prefix(&self.0[..i]))),
169        }
170    }
171
172    /// If that `QName` represents `"xmlns"` series of names, returns `Some`,
173    /// otherwise `None` is returned.
174    ///
175    /// # Examples
176    ///
177    /// ```
178    /// # use quick_xml::name::{QName, PrefixDeclaration};
179    /// let qname = QName("xmlns");
180    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Default));
181    ///
182    /// let qname = QName("xmlns:prefix");
183    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named("prefix")));
184    ///
185    /// // Be aware that this method does not check the validity of the prefix - it can be empty!
186    /// let qname = QName("xmlns:");
187    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named("")));
188    ///
189    /// let qname = QName("other-name");
190    /// assert_eq!(qname.as_namespace_binding(), None);
191    ///
192    /// // https://www.w3.org/TR/xml-names11/#xmlReserved
193    /// let qname = QName("xmlns-reserved-name");
194    /// assert_eq!(qname.as_namespace_binding(), None);
195    /// ```
196    pub fn as_namespace_binding(&self) -> Option<PrefixDeclaration<'a>> {
197        if self.0.starts_with("xmlns") {
198            return match self.0.as_bytes().get(5) {
199                None => Some(PrefixDeclaration::Default),
200                Some(&b':') => Some(PrefixDeclaration::Named(&self.0[6..])),
201                _ => None,
202            };
203        }
204        None
205    }
206
207    /// Returns the index in the name where prefix ended
208    #[inline(always)]
209    fn index(&self) -> Option<usize> {
210        self.0.find(':')
211    }
212}
213
214impl<'a> Debug for QName<'a> {
215    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
216        write!(f, "QName({})", self.0)
217    }
218}
219impl<'a> AsRef<str> for QName<'a> {
220    #[inline]
221    fn as_ref(&self) -> &str {
222        self.0
223    }
224}
225
226////////////////////////////////////////////////////////////////////////////////////////////////////
227
228/// A [local (unqualified) name] of an element or an attribute, i.e. a name
229/// without [prefix](Prefix).
230///
231/// [local (unqualified) name]: https://www.w3.org/TR/xml-names11/#dt-localname
232#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
233#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
234pub struct LocalName<'a>(pub(crate) &'a str);
235impl<'a> LocalName<'a> {
236    /// Converts this name to an internal slice representation.
237    #[inline(always)]
238    pub const fn into_inner(self) -> &'a str {
239        self.0
240    }
241}
242
243impl<'a> Debug for LocalName<'a> {
244    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
245        write!(f, "LocalName({})", self.0)
246    }
247}
248
249impl<'a> AsRef<str> for LocalName<'a> {
250    #[inline]
251    fn as_ref(&self) -> &str {
252        self.0
253    }
254}
255
256impl<'a> From<QName<'a>> for LocalName<'a> {
257    /// Creates `LocalName` from a [`QName`]
258    ///
259    /// # Examples
260    ///
261    /// ```
262    /// # use quick_xml::name::{LocalName, QName};
263    ///
264    /// let local: LocalName = QName("unprefixed").into();
265    /// assert_eq!(local.into_inner(), "unprefixed");
266    ///
267    /// let local: LocalName = QName("some:prefix").into();
268    /// assert_eq!(local.into_inner(), "prefix");
269    /// ```
270    #[inline]
271    fn from(name: QName<'a>) -> Self {
272        Self(name.index().map_or(name.0, |i| &name.0[i + 1..]))
273    }
274}
275
276////////////////////////////////////////////////////////////////////////////////////////////////////
277
278/// A [namespace prefix] part of the [qualified name](QName) of an element tag
279/// or an attribute: a `prefix` in `<prefix:local-element-name>` or
280/// `prefix:local-attribute-name="attribute value"`.
281///
282/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
283#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
284#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
285pub struct Prefix<'a>(&'a str);
286impl<'a> Prefix<'a> {
287    /// Extracts internal slice
288    #[inline(always)]
289    pub const fn into_inner(self) -> &'a str {
290        self.0
291    }
292
293    /// Checks if this prefix is a special prefix `xml`.
294    #[inline(always)]
295    pub const fn is_xml(&self) -> bool {
296        matches!(self.0.as_bytes(), b"xml")
297    }
298
299    /// Checks if this prefix is a special prefix `xmlns`.
300    #[inline(always)]
301    pub const fn is_xmlns(&self) -> bool {
302        matches!(self.0.as_bytes(), b"xmlns")
303    }
304}
305
306impl<'a> Debug for Prefix<'a> {
307    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
308        write!(f, "Prefix({})", self.0)
309    }
310}
311
312impl<'a> AsRef<str> for Prefix<'a> {
313    #[inline]
314    fn as_ref(&self) -> &str {
315        self.0
316    }
317}
318
319////////////////////////////////////////////////////////////////////////////////////////////////////
320
321/// A namespace prefix declaration, `xmlns` or `xmlns:<name>`, as defined in
322/// [XML Schema specification](https://www.w3.org/TR/xml-names11/#ns-decl)
323#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
324pub enum PrefixDeclaration<'a> {
325    /// XML attribute binds a default namespace. Corresponds to `xmlns` in `xmlns="..."`
326    Default,
327    /// XML attribute binds a specified prefix to a namespace. Corresponds to a
328    /// `prefix` in `xmlns:prefix="..."`, which is stored as payload of this variant.
329    Named(&'a str),
330}
331
332impl<'a> Debug for PrefixDeclaration<'a> {
333    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
334        match self {
335            Self::Default => f.write_str("PrefixDeclaration::Default"),
336            Self::Named(prefix) => {
337                write!(f, "PrefixDeclaration::Named({})", prefix)
338            }
339        }
340    }
341}
342
343////////////////////////////////////////////////////////////////////////////////////////////////////
344
345/// A [namespace name] that is declared in a `xmlns[:prefix]="namespace name"`.
346///
347/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
348#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
349#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
350pub struct Namespace<'a>(pub &'a str);
351impl<'a> Namespace<'a> {
352    /// Converts this namespace to an internal slice representation.
353    ///
354    /// This is [non-normalized] attribute value, i.e. any entity references is not
355    /// expanded and space characters are not removed. This means, that different
356    /// string slices, returned from this method, can represent the same namespace
357    /// and would be treated by parser as identical.
358    ///
359    /// For example, if the entity **eacute** has been defined to be **é**,
360    /// the empty tags below all contain namespace declarations binding the
361    /// prefix `p` to the same [IRI reference], `http://example.org/rosé`.
362    ///
363    /// ```xml
364    /// <p:foo xmlns:p="http://example.org/rosé" />
365    /// <p:foo xmlns:p="http://example.org/ros&#xe9;" />
366    /// <p:foo xmlns:p="http://example.org/ros&#xE9;" />
367    /// <p:foo xmlns:p="http://example.org/ros&#233;" />
368    /// <p:foo xmlns:p="http://example.org/ros&eacute;" />
369    /// ```
370    ///
371    /// This is because XML entity references are expanded during attribute value
372    /// normalization.
373    ///
374    /// [non-normalized]: https://www.w3.org/TR/xml11/#AVNormalize
375    /// [IRI reference]: https://datatracker.ietf.org/doc/html/rfc3987
376    #[inline(always)]
377    pub const fn into_inner(self) -> &'a str {
378        self.0
379    }
380    //TODO: implement value normalization and use it when comparing namespaces
381}
382
383impl<'a> Debug for Namespace<'a> {
384    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
385        write!(f, "Namespace({})", self.0)
386    }
387}
388
389impl<'a> AsRef<str> for Namespace<'a> {
390    #[inline]
391    fn as_ref(&self) -> &str {
392        self.0
393    }
394}
395
396////////////////////////////////////////////////////////////////////////////////////////////////////
397
398/// Result of [prefix] resolution which creates by [`NamespaceResolver::resolve`],
399/// [`NsReader::read_resolved_event`] and
400/// [`NsReader::read_resolved_event_into`] methods.
401///
402/// [prefix]: Prefix
403/// [`NsReader::read_resolved_event`]: crate::reader::NsReader::read_resolved_event
404/// [`NsReader::read_resolved_event_into`]: crate::reader::NsReader::read_resolved_event_into
405#[derive(Clone, PartialEq, Eq, Hash)]
406pub enum ResolveResult<'ns> {
407    /// Qualified name does not contain prefix, and resolver does not define
408    /// default namespace, so name is not bound to any namespace
409    Unbound,
410    /// [`Prefix`] resolved to the specified namespace
411    Bound(Namespace<'ns>),
412    /// Specified prefix was not found in scope
413    Unknown(String),
414}
415
416impl<'ns> Debug for ResolveResult<'ns> {
417    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
418        match self {
419            Self::Unbound => write!(f, "Unbound"),
420            Self::Bound(ns) => write!(f, "Bound({:?})", ns),
421            Self::Unknown(p) => write!(f, "Unknown({})", p),
422        }
423    }
424}
425
426impl<'ns> TryFrom<ResolveResult<'ns>> for Option<Namespace<'ns>> {
427    type Error = NamespaceError;
428
429    /// Try to convert this result to an optional namespace and returns
430    /// [`NamespaceError::UnknownPrefix`] if this result represents unknown prefix
431    fn try_from(result: ResolveResult<'ns>) -> Result<Self, NamespaceError> {
432        use ResolveResult::*;
433
434        match result {
435            Unbound => Ok(None),
436            Bound(ns) => Ok(Some(ns)),
437            Unknown(p) => Err(NamespaceError::UnknownPrefix(p)),
438        }
439    }
440}
441
442////////////////////////////////////////////////////////////////////////////////////////////////////
443
444/// An entry that contains index into the buffer with namespace bindings.
445///
446/// Defines a mapping from *[namespace prefix]* to *[namespace name]*.
447/// If prefix is empty, defines a *default namespace* binding that applies to
448/// unprefixed element names (unprefixed attribute names do not bind to any
449/// namespace and they processing is dependent on the element in which their
450/// defined).
451///
452/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
453/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
454#[derive(Debug, Clone)]
455struct NamespaceBinding {
456    /// Index of the namespace in the buffer
457    start: usize,
458    /// Length of the prefix
459    /// * if greater than zero, then binds this namespace to the slice
460    ///   `[start..start + prefix_len]` in the buffer.
461    /// * else defines the current default namespace.
462    prefix_len: usize,
463    /// The length of a namespace name (the URI) of this namespace declaration.
464    /// Name started just after prefix and extend for `value_len` bytes.
465    ///
466    /// The XML standard [specifies] that an empty namespace value 'removes' a namespace declaration
467    /// for the extent of its scope. For prefix declarations that's not very interesting, but it is
468    /// vital for default namespace declarations. With `xmlns=""` you can revert back to the default
469    /// behaviour of leaving unqualified element names unqualified.
470    ///
471    /// [specifies]: https://www.w3.org/TR/xml-names11/#scoping
472    value_len: usize,
473    /// Level of nesting at which this namespace was declared. The declaring element is included,
474    /// i.e., a declaration on the document root has `level = 1`.
475    /// This is used to pop the namespace when the element gets closed.
476    level: u16,
477}
478
479impl NamespaceBinding {
480    /// Get the namespace prefix, bound to this namespace declaration, or `None`,
481    /// if this declaration is for default namespace (`xmlns="..."`).
482    #[inline]
483    const fn prefix<'b>(&self, ns_buffer: &'b str) -> Option<Prefix<'b>> {
484        if self.prefix_len == 0 {
485            None
486        } else {
487            // We use split_at to get [start..start + prefix_len]
488            // in a constant way
489            let (_, prefix) = ns_buffer.split_at(self.start);
490            let (prefix, _) = prefix.split_at(self.prefix_len);
491            Some(Prefix(prefix))
492        }
493    }
494
495    /// Gets the namespace name (the URI) slice out of namespace buffer
496    ///
497    /// Returns `None` if namespace for this prefix was explicitly removed from
498    /// scope, using `xmlns[:prefix]=""`
499    #[inline]
500    const fn namespace<'ns>(&self, buffer: &'ns str) -> ResolveResult<'ns> {
501        if self.value_len == 0 {
502            ResolveResult::Unbound
503        } else {
504            // We use split_at to get [start + prefix_len..start + prefix_len + value_len]
505            // in a constant way
506            let (_, ns) = buffer.split_at(self.start + self.prefix_len);
507            let (ns, _) = ns.split_at(self.value_len);
508            ResolveResult::Bound(Namespace(ns))
509        }
510    }
511}
512
513/// A storage for currently defined namespace bindings, which is used to resolve
514/// prefixes into namespaces.
515///
516/// Holds all internal logic to push/pop namespaces with their levels.
517#[derive(Clone, Debug)]
518pub struct NamespaceResolver {
519    /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
520    /// and an `=`) and namespace values.
521    buffer: String,
522    /// A stack of namespace bindings to prefixes that currently in scope
523    bindings: Vec<NamespaceBinding>,
524    /// The number of open tags at the moment. We need to keep track of this to know which namespace
525    /// declarations to remove when we encounter an `End` event.
526    nesting_level: u16,
527    /// Maximum number of user-declared `xmlns` / `xmlns:*` namespace bindings
528    /// allowed in scope at once, not counting the two reserved bindings for
529    /// `xml` and `xmlns`. See [`set_max_namespace_bindings`](Self::set_max_namespace_bindings).
530    max_namespace_bindings: usize,
531}
532
533/// Default limit on the number of `xmlns` / `xmlns:*` namespace bindings allowed in scope at
534/// once in a [`NamespaceResolver`], not counting the two reserved bindings (`xml` and `xmlns`)
535/// that are always present.
536///
537/// Real-world XML dialects (XHTML, SVG, SOAP, RSS, RRDP, ...) declare a handful of namespaces,
538/// almost always on the root element; 128 is significantly more than what most legitimate documents
539/// would declare, while bounding both the heap allocated and the cost of prefix resolution
540/// (which scans the binding stack).
541pub const DEFAULT_MAX_NAMESPACE_BINDINGS: usize = 128;
542
543/// The number of namespace bindings pre-loaded by [`NamespaceResolver::default()`]
544/// (`xml` and `xmlns`). Subtracted from `bindings.len()` when checking against
545/// the user-facing [`max_namespace_bindings`](NamespaceResolver::max_namespace_bindings)
546/// limit, so these built-in bindings don't count against the user's limit.
547const BUILTIN_NAMESPACE_BINDINGS: usize = 2;
548
549/// This constant defines one the of [reserved namespaces] for the xml standard.
550///
551/// The prefix `xml` is by definition bound to the namespace name
552/// `http://www.w3.org/XML/1998/namespace`. It may, but need not, be declared, and must not be
553/// undeclared or bound to any other namespace name. Other prefixes must not be bound to this
554/// namespace name, and it must not be declared as the default namespace.
555///
556/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
557const RESERVED_NAMESPACE_XML: (Prefix, Namespace) = (
558    Prefix("xml"),
559    Namespace("http://www.w3.org/XML/1998/namespace"),
560);
561/// This constant defines one of the [reserved namespaces] for the xml standard.
562///
563/// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
564/// to the namespace name `http://www.w3.org/2000/xmlns/`. It must not be declared or
565/// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
566/// declared as the default namespace. Element names must not have the prefix `xmlns`.
567///
568/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
569const RESERVED_NAMESPACE_XMLNS: (Prefix, Namespace) =
570    (Prefix("xmlns"), Namespace("http://www.w3.org/2000/xmlns/"));
571
572impl Default for NamespaceResolver {
573    fn default() -> Self {
574        let mut buffer = String::new();
575        let mut bindings = Vec::new();
576        for ent in &[RESERVED_NAMESPACE_XML, RESERVED_NAMESPACE_XMLNS] {
577            let prefix = ent.0.into_inner();
578            let uri = ent.1.into_inner();
579            bindings.push(NamespaceBinding {
580                start: buffer.len(),
581                prefix_len: prefix.len(),
582                value_len: uri.len(),
583                level: 0,
584            });
585            buffer.push_str(prefix);
586            buffer.push_str(uri);
587        }
588
589        Self {
590            buffer,
591            bindings,
592            nesting_level: 0,
593            max_namespace_bindings: DEFAULT_MAX_NAMESPACE_BINDINGS,
594        }
595    }
596}
597
598impl NamespaceResolver {
599    /// Adds new binding of prefix to namespace, returns the result of operation.
600    ///
601    /// Binding will be added on current nesting level and will be removed, when
602    /// level will be [popped out].
603    ///
604    /// The operation may fail if you try to (re-)declare reserved prefixes `xml` and `xmlns`.
605    ///
606    /// Note, that method does not check if namespace was already added on that level.
607    /// Use `resolver.bindings_of(resolver.level()).any()` if you want to check that.
608    /// New definition will be added and replace the old.
609    ///
610    /// Implementation detail: memory occupied by old binding of that level still will be used.
611    ///
612    /// ```
613    /// # use pretty_assertions::assert_eq;
614    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
615    /// #
616    /// let mut resolver = NamespaceResolver::default();
617    /// // names without prefix are unbound by default
618    /// assert_eq!(
619    ///     resolver.resolve_element(QName("name")).0,
620    ///     ResolveResult::Unbound,
621    /// );
622    /// // names with undeclared prefix are unknown
623    /// assert_eq!(
624    ///     resolver.resolve_element(QName("ns:name")).0,
625    ///     ResolveResult::Unknown("ns".to_string()),
626    /// );
627    ///
628    /// resolver.add(PrefixDeclaration::Default, Namespace("example.com"));
629    /// resolver.add(PrefixDeclaration::Named("ns"), Namespace("my:namespace"));
630    ///
631    /// assert_eq!(
632    ///     resolver.resolve_element(QName("name")).0,
633    ///     ResolveResult::Bound(Namespace("example.com")),
634    /// );
635    /// assert_eq!(
636    ///     resolver.resolve_element(QName("ns:name")).0,
637    ///     ResolveResult::Bound(Namespace("my:namespace")),
638    /// );
639    ///
640    /// // adding empty namespace clears the binding
641    /// resolver.add(PrefixDeclaration::Default, Namespace(""));
642    /// resolver.add(PrefixDeclaration::Named("ns"), Namespace(""));
643    ///
644    /// assert_eq!(
645    ///     resolver.resolve_element(QName("name")).0,
646    ///     ResolveResult::Unbound,
647    /// );
648    /// assert_eq!(
649    ///     resolver.resolve_element(QName("ns:name")).0,
650    ///     ResolveResult::Unknown("ns".to_string()),
651    /// );
652    /// ```
653    /// [popped out]: Self::pop
654    pub fn add(
655        &mut self,
656        prefix: PrefixDeclaration,
657        namespace: Namespace,
658    ) -> Result<(), NamespaceError> {
659        let level = self.nesting_level;
660        match prefix {
661            PrefixDeclaration::Default => {
662                if self
663                    .bindings
664                    .len()
665                    .saturating_sub(BUILTIN_NAMESPACE_BINDINGS)
666                    >= self.max_namespace_bindings
667                {
668                    return Err(NamespaceError::TooManyBindings(self.max_namespace_bindings));
669                }
670                let start = self.buffer.len();
671                self.buffer.push_str(namespace.0);
672                self.bindings.push(NamespaceBinding {
673                    start,
674                    prefix_len: 0,
675                    value_len: namespace.0.len(),
676                    level,
677                });
678            }
679            PrefixDeclaration::Named("xml") => {
680                if namespace != RESERVED_NAMESPACE_XML.1 {
681                    // error, `xml` prefix explicitly set to different value
682                    return Err(NamespaceError::InvalidXmlPrefixBind(
683                        namespace.0.to_string(),
684                    ));
685                }
686                // don't add another NamespaceEntry for the `xml` namespace prefix
687            }
688            PrefixDeclaration::Named("xmlns") => {
689                // error, `xmlns` prefix explicitly set
690                return Err(NamespaceError::InvalidXmlnsPrefixBind(
691                    namespace.0.to_string(),
692                ));
693            }
694            PrefixDeclaration::Named(prefix) => {
695                if namespace == RESERVED_NAMESPACE_XML.1 {
696                    // error, non-`xml` prefix set to xml uri
697                    return Err(NamespaceError::InvalidPrefixForXml(prefix.to_string()));
698                } else if namespace == RESERVED_NAMESPACE_XMLNS.1 {
699                    // error, non-`xmlns` prefix set to xmlns uri
700                    return Err(NamespaceError::InvalidPrefixForXmlns(prefix.to_string()));
701                }
702
703                if self
704                    .bindings
705                    .len()
706                    .saturating_sub(BUILTIN_NAMESPACE_BINDINGS)
707                    >= self.max_namespace_bindings
708                {
709                    return Err(NamespaceError::TooManyBindings(self.max_namespace_bindings));
710                }
711                let start = self.buffer.len();
712                self.buffer.push_str(prefix);
713                self.buffer.push_str(namespace.0);
714                self.bindings.push(NamespaceBinding {
715                    start,
716                    prefix_len: prefix.len(),
717                    value_len: namespace.0.len(),
718                    level,
719                });
720            }
721        }
722        Ok(())
723    }
724
725    /// Begins a new scope and add to it all [namespace bindings] that found in
726    /// the specified start element.
727    ///
728    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
729    pub fn push(&mut self, start: &BytesStart) -> Result<(), NamespaceError> {
730        self.nesting_level = self
731            .nesting_level
732            .checked_add(1)
733            .ok_or(NamespaceError::TooDeeplyNested(u16::MAX as usize))?;
734        // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns'
735        // (default namespace) attribute.
736        for a in start.attributes().with_checks(false) {
737            if let Ok(Attribute { key: k, value: v }) = a {
738                if let Some(prefix) = k.as_namespace_binding() {
739                    self.add(prefix, Namespace(&v))?;
740                }
741            } else {
742                break;
743            }
744        }
745        Ok(())
746    }
747
748    /// Returns the maximum number of user-declared `xmlns` / `xmlns:*` namespace
749    /// bindings allowed in scope at once (not counting the two reserved bindings
750    /// for `xml` and `xmlns`).
751    ///
752    /// Defaults to [`DEFAULT_MAX_NAMESPACE_BINDINGS`].
753    #[inline]
754    pub const fn max_namespace_bindings(&self) -> usize {
755        self.max_namespace_bindings
756    }
757
758    /// Sets the maximum number of user-declared `xmlns` / `xmlns:*` namespace bindings
759    /// allowed in scope at once. The two reserved bindings (`xml` and `xmlns`) do not
760    /// count toward this limit.
761    ///
762    /// [`add`](Self::add) is called by [`push`](Self::push), which is called by
763    /// [`NsReader`](crate::reader::NsReader) for every `Start`/`Empty` event *before* the event
764    /// is returned to the caller. This limit bounds both the heap allocated for namespace
765    /// bindings and the cost of prefix resolution (which scans the binding stack). See
766    /// <https://github.com/tafia/quick-xml/issues/970> and <https://github.com/tafia/quick-xml/issues/980>.
767    ///
768    /// Pass `usize::MAX` to disable the limit.
769    #[inline]
770    pub fn set_max_namespace_bindings(&mut self, limit: usize) -> &mut Self {
771        self.max_namespace_bindings = limit;
772        self
773    }
774
775    /// Ends a top-most scope by popping all [namespace bindings], that was added by
776    /// last call to [`Self::push()`] and [`Self::add()`].
777    ///
778    /// [namespace bindings]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
779    #[inline]
780    pub fn pop(&mut self) {
781        self.set_level(self.nesting_level.saturating_sub(1));
782    }
783
784    /// Runs action as if all namespaces from the specified `start` element were added
785    /// to the resolver, but without actually changing the resolver state.
786    pub fn with<F, R>(&mut self, start: &BytesStart, mut action: F) -> Result<R, NamespaceError>
787    where
788        F: FnMut(&Self) -> R,
789    {
790        self.push(start)?;
791        let result = action(self);
792        self.pop();
793        Ok(result)
794    }
795
796    /// Sets new number of [`push`] calls that were not followed by [`pop`] calls.
797    ///
798    /// When set to value lesser than current [`level`], behaves as if [`pop`]
799    /// will be called until the level reaches the corresponding value.
800    ///
801    /// When set to value bigger than current [`level`] just increases internal
802    /// counter. You may need to call [`pop`] more times that required before.
803    ///
804    /// # Example
805    ///
806    /// ```
807    /// # use pretty_assertions::assert_eq;
808    /// # use quick_xml::events::BytesStart;
809    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
810    /// #
811    /// let mut resolver = NamespaceResolver::default();
812    ///
813    /// assert_eq!(resolver.level(), 0);
814    ///
815    /// resolver.push(&BytesStart::new("tag"));
816    /// assert_eq!(resolver.level(), 1);
817    ///
818    /// resolver.set_level(10);
819    /// assert_eq!(resolver.level(), 10);
820    ///
821    /// resolver.pop();
822    /// assert_eq!(resolver.level(), 9);
823    ///
824    /// resolver.set_level(0);
825    /// assert_eq!(resolver.level(), 0);
826    ///
827    /// // pop from empty resolver does nothing
828    /// resolver.pop();
829    /// assert_eq!(resolver.level(), 0);
830    /// ```
831    ///
832    /// [`push`]: Self::push
833    /// [`pop`]: Self::pop
834    /// [`level`]: Self::level
835    pub fn set_level(&mut self, level: u16) {
836        self.nesting_level = level;
837        // from the back (most deeply nested scope), look for the first scope that is still valid
838        match self.bindings.iter().rposition(|n| n.level <= level) {
839            // none of the namespaces are valid, remove all of them
840            None => {
841                self.buffer.clear();
842                self.bindings.clear();
843            }
844            // drop all namespaces past the last valid namespace
845            Some(last_valid_pos) => {
846                if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) {
847                    self.buffer.truncate(len);
848                    self.bindings.truncate(last_valid_pos + 1);
849                }
850            }
851        }
852    }
853
854    /// Resolves a potentially qualified **element name** or **attribute name**
855    /// into _(namespace name, local name)_.
856    ///
857    /// _Qualified_ names have the form `local-name` or `prefix:local-name` where the `prefix`
858    /// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
859    /// The namespace prefix can be defined on the same element as the name in question.
860    ///
861    /// The method returns following results depending on the `name` shape, `attribute` flag
862    /// and the presence of the default namespace on element or any of its parents:
863    ///
864    /// |use_default|`xmlns="..."`|QName              |ResolveResult          |LocalName
865    /// |-----------|-------------|-------------------|-----------------------|------------
866    /// |`false`    |_(any)_      |`local-name`       |[`Unbound`]            |`local-name`
867    /// |`false`    |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
868    /// |`true`     |Not defined  |`local-name`       |[`Unbound`]            |`local-name`
869    /// |`true`     |Defined      |`local-name`       |[`Bound`] (to `xmlns`) |`local-name`
870    /// |`true`     |_(any)_      |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
871    ///
872    /// # Parameters
873    /// - `name`: probably qualified name to resolve;
874    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
875    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
876    ///   For attribute names this should be set to `false` and for element names to `true`.
877    ///
878    /// # Lifetimes
879    ///
880    /// - `'n`: lifetime of a name. Returned local name will be bound to the same
881    ///   lifetime as the name in question.
882    /// - returned namespace name will be bound to the resolver itself
883    ///
884    /// [`Bound`]: ResolveResult::Bound
885    /// [`Unbound`]: ResolveResult::Unbound
886    /// [`Unknown`]: ResolveResult::Unknown
887    #[inline]
888    pub fn resolve<'n>(
889        &self,
890        name: QName<'n>,
891        use_default: bool,
892    ) -> (ResolveResult<'_>, LocalName<'n>) {
893        let (local_name, prefix) = name.decompose();
894        (self.resolve_prefix(prefix, use_default), local_name)
895    }
896
897    /// Convenient method to call `resolve(name, true)`. May be used to clearly
898    /// express that we want to resolve an element name, and not an attribute name.
899    #[inline]
900    pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
901        self.resolve(name, true)
902    }
903
904    /// Convenient method to call `resolve(name, false)`. May be used to clearly
905    /// express that we want to resolve an attribute name, and not an element name.
906    #[inline]
907    pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult<'_>, LocalName<'n>) {
908        self.resolve(name, false)
909    }
910
911    /// Finds a [namespace name] for a given event, if applicable.
912    ///
913    /// Namespace is resolved only for [`Start`], [`Empty`] and [`End`] events.
914    /// For all other events the concept of namespace is not defined, so
915    /// a [`ResolveResult::Unbound`] is returned.
916    ///
917    /// # Examples
918    ///
919    /// ```
920    /// # use pretty_assertions::assert_eq;
921    /// use quick_xml::events::Event;
922    /// use quick_xml::name::{Namespace, QName, ResolveResult::*};
923    /// use quick_xml::reader::NsReader;
924    ///
925    /// let mut reader = NsReader::from_str(r#"
926    ///     <x:tag1 xmlns:x="www.xxxx" xmlns:y="www.yyyy" att1 = "test">
927    ///        <y:tag2><!--Test comment-->Test</y:tag2>
928    ///        <y:tag2>Test 2</y:tag2>
929    ///     </x:tag1>
930    /// "#);
931    /// reader.config_mut().trim_text(true);
932    ///
933    /// let mut count = 0;
934    /// let mut txt = Vec::new();
935    /// loop {
936    ///     let event = reader.read_event().unwrap();
937    ///     match reader.resolver().resolve_event(event) {
938    ///         (Bound(Namespace("www.xxxx")), Event::Start(e)) => {
939    ///             count += 1;
940    ///             assert_eq!(e.local_name(), QName("tag1").into());
941    ///         }
942    ///         (Bound(Namespace("www.yyyy")), Event::Start(e)) => {
943    ///             count += 1;
944    ///             assert_eq!(e.local_name(), QName("tag2").into());
945    ///         }
946    ///         (_, Event::Start(_)) => unreachable!(),
947    ///
948    ///         (_, Event::Text(e)) => {
949    ///             txt.push(e.into_inner().into_owned())
950    ///         }
951    ///         (_, Event::Eof) => break,
952    ///         _ => (),
953    ///     }
954    /// }
955    /// assert_eq!(count, 3);
956    /// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
957    /// ```
958    ///
959    /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
960    /// [`Empty`]: Event::Empty
961    /// [`Start`]: Event::Start
962    /// [`End`]: Event::End
963    pub fn resolve_event<'i>(&self, event: Event<'i>) -> (ResolveResult<'_>, Event<'i>) {
964        use Event::*;
965
966        match event {
967            Empty(e) => (self.resolve_prefix(e.name().prefix(), true), Empty(e)),
968            Start(e) => (self.resolve_prefix(e.name().prefix(), true), Start(e)),
969            End(e) => (self.resolve_prefix(e.name().prefix(), true), End(e)),
970            e => (ResolveResult::Unbound, e),
971        }
972    }
973
974    /// Resolves given optional prefix (usually got from [`QName`]) into a corresponding namespace.
975    ///
976    /// # Parameters
977    /// - `prefix`: prefix to resolve, usually result of [`QName::prefix()`];
978    /// - `use_default`: whether to try to translate `None` prefix to the currently default namespace
979    ///   (bound using `xmlns="default namespace"`) or return [`ResolveResult::Unbound`].
980    ///   For attribute names this should be set to `false` and for element names to `true`.
981    pub fn resolve_prefix(&self, prefix: Option<Prefix>, use_default: bool) -> ResolveResult<'_> {
982        // Find the last defined binding that corresponds to the given prefix
983        let mut iter = self.bindings.iter().rev();
984        match (prefix, use_default) {
985            // Attribute name has no explicit prefix -> Unbound
986            (None, false) => ResolveResult::Unbound,
987            // Element name has no explicit prefix -> find nearest xmlns binding
988            (None, true) => match iter.find(|n| n.prefix_len == 0) {
989                Some(n) => n.namespace(&self.buffer),
990                None => ResolveResult::Unbound,
991            },
992            // Attribute or element name with explicit prefix
993            (Some(p), _) => match iter.find(|n| n.prefix(&self.buffer) == prefix) {
994                Some(n) if n.value_len != 0 => n.namespace(&self.buffer),
995                // Not found or binding reset (corresponds to `xmlns:p=""`)
996                _ => ResolveResult::Unknown(p.into_inner().to_string()),
997            },
998        }
999    }
1000
1001    /// Returns all the bindings currently in effect except the default `xml` and `xmlns` bindings.
1002    ///
1003    /// # Examples
1004    ///
1005    /// This example shows what results the returned iterator would return after
1006    /// reading each event of a simple XML.
1007    ///
1008    /// ```
1009    /// # use pretty_assertions::assert_eq;
1010    /// use quick_xml::name::{Namespace, PrefixDeclaration};
1011    /// use quick_xml::NsReader;
1012    ///
1013    /// let src = "<root>
1014    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
1015    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
1016    ///       <c/>
1017    ///     </b>
1018    ///     <d/>
1019    ///   </a>
1020    /// </root>";
1021    /// let mut reader = NsReader::from_str(src);
1022    /// reader.config_mut().trim_text(true);
1023    /// // No bindings at the beginning
1024    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
1025    ///
1026    /// reader.read_resolved_event()?; // <root>
1027    /// // No bindings declared on root
1028    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
1029    ///
1030    /// reader.read_resolved_event()?; // <a>
1031    /// // Two bindings declared on "a"
1032    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1033    ///     (PrefixDeclaration::Default, Namespace("a1")),
1034    ///     (PrefixDeclaration::Named("a"), Namespace("a2"))
1035    /// ]);
1036    ///
1037    /// reader.read_resolved_event()?; // <b>
1038    /// // The default prefix got overridden and new "b" prefix
1039    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1040    ///     (PrefixDeclaration::Named("a"), Namespace("a2")),
1041    ///     (PrefixDeclaration::Default, Namespace("b1")),
1042    ///     (PrefixDeclaration::Named("b"), Namespace("b2"))
1043    /// ]);
1044    ///
1045    /// reader.read_resolved_event()?; // <c/>
1046    /// // Still the same
1047    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1048    ///     (PrefixDeclaration::Named("a"), Namespace("a2")),
1049    ///     (PrefixDeclaration::Default, Namespace("b1")),
1050    ///     (PrefixDeclaration::Named("b"), Namespace("b2"))
1051    /// ]);
1052    ///
1053    /// reader.read_resolved_event()?; // </b>
1054    /// // Still the same
1055    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1056    ///     (PrefixDeclaration::Named("a"), Namespace("a2")),
1057    ///     (PrefixDeclaration::Default, Namespace("b1")),
1058    ///     (PrefixDeclaration::Named("b"), Namespace("b2"))
1059    /// ]);
1060    ///
1061    /// reader.read_resolved_event()?; // <d/>
1062    /// // </b> got closed so back to the bindings declared on <a>
1063    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1064    ///     (PrefixDeclaration::Default, Namespace("a1")),
1065    ///     (PrefixDeclaration::Named("a"), Namespace("a2"))
1066    /// ]);
1067    ///
1068    /// reader.read_resolved_event()?; // </a>
1069    /// // Still the same
1070    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![
1071    ///     (PrefixDeclaration::Default, Namespace("a1")),
1072    ///     (PrefixDeclaration::Named("a"), Namespace("a2"))
1073    /// ]);
1074    ///
1075    /// reader.read_resolved_event()?; // </root>
1076    /// // <a> got closed
1077    /// assert_eq!(reader.resolver().bindings().collect::<Vec<_>>(), vec![]);
1078    /// # quick_xml::Result::Ok(())
1079    /// ```
1080    #[inline]
1081    pub const fn bindings(&self) -> NamespaceBindingsIter<'_> {
1082        NamespaceBindingsIter {
1083            resolver: self,
1084            // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns:
1085            cursor: 2,
1086        }
1087    }
1088
1089    /// Returns all the bindings on the specified level, including the default
1090    /// `xml` and `xmlns` bindings.
1091    ///
1092    /// # Parameters
1093    /// - `level`: the nesting level of an XML tag. The document without tags has
1094    ///   level 0, at which default bindings are declared. The root tag has level 1
1095    ///   and all other tags has levels > 1. If specify level more than [current], the
1096    ///   empty iterator is returned.
1097    ///
1098    /// # Examples
1099    ///
1100    /// This example shows what results the returned iterator would return on each
1101    /// level after reaning some events of a simple XML.
1102    ///
1103    /// ```
1104    /// # use pretty_assertions::assert_eq;
1105    /// use quick_xml::name::{Namespace, PrefixDeclaration};
1106    /// use quick_xml::NsReader;
1107    ///
1108    /// let src = "<root>
1109    ///   <a xmlns=\"a1\" xmlns:a=\"a2\">
1110    ///     <b xmlns=\"b1\" xmlns:b=\"b2\">
1111    ///       <c/>
1112    ///     </b>
1113    ///     <d/>
1114    ///   </a>
1115    /// </root>";
1116    /// let mut reader = NsReader::from_str(src);
1117    /// reader.config_mut().trim_text(true);
1118    /// reader.read_resolved_event()?; // <root>
1119    /// reader.read_resolved_event()?; // <a>
1120    /// reader.read_resolved_event()?; // <b>
1121    /// reader.read_resolved_event()?; // <c/>
1122    ///
1123    /// // Default bindings at the beginning
1124    /// assert_eq!(reader.resolver().bindings_of(0).collect::<Vec<_>>(), vec![
1125    ///     (PrefixDeclaration::Named("xml"), Namespace("http://www.w3.org/XML/1998/namespace")),
1126    ///     (PrefixDeclaration::Named("xmlns"), Namespace("http://www.w3.org/2000/xmlns/")),
1127    /// ]);
1128    ///
1129    /// // No bindings declared on root
1130    /// assert_eq!(reader.resolver().bindings_of(1).collect::<Vec<_>>(), vec![]);
1131    ///
1132    /// // Two bindings declared on "a"
1133    /// assert_eq!(reader.resolver().bindings_of(2).collect::<Vec<_>>(), vec![
1134    ///     (PrefixDeclaration::Default, Namespace("a1")),
1135    ///     (PrefixDeclaration::Named("a"), Namespace("a2")),
1136    /// ]);
1137    ///
1138    /// // Two bindings declared on "b"
1139    /// assert_eq!(reader.resolver().bindings_of(3).collect::<Vec<_>>(), vec![
1140    ///     (PrefixDeclaration::Default, Namespace("b1")),
1141    ///     (PrefixDeclaration::Named("b"), Namespace("b2")),
1142    /// ]);
1143    ///
1144    /// // No bindings declared on "c"
1145    /// assert_eq!(reader.resolver().bindings_of(4).collect::<Vec<_>>(), vec![]);
1146    ///
1147    /// // No bindings on non-existent level
1148    /// assert_eq!(reader.resolver().bindings_of(5).collect::<Vec<_>>(), vec![]);
1149    /// # quick_xml::Result::Ok(())
1150    /// ```
1151    ///
1152    /// [current]: Self::level
1153    pub const fn bindings_of(&self, level: u16) -> NamespaceBindingsOfLevelIter<'_> {
1154        NamespaceBindingsOfLevelIter {
1155            resolver: self,
1156            cursor: 0,
1157            level,
1158        }
1159    }
1160
1161    /// Returns the number of [`push`] calls that were not followed by [`pop`] calls.
1162    ///
1163    /// Due to use of `u16` for level number the number of nested tags in XML
1164    /// are limited by [`u16::MAX`], but that is enough for any real application.
1165    ///
1166    /// # Example
1167    ///
1168    /// ```
1169    /// # use pretty_assertions::assert_eq;
1170    /// # use quick_xml::events::BytesStart;
1171    /// # use quick_xml::name::{Namespace, NamespaceResolver, PrefixDeclaration, QName, ResolveResult};
1172    /// #
1173    /// let mut resolver = NamespaceResolver::default();
1174    ///
1175    /// assert_eq!(resolver.level(), 0);
1176    ///
1177    /// resolver.push(&BytesStart::new("tag"));
1178    /// assert_eq!(resolver.level(), 1);
1179    ///
1180    /// resolver.pop();
1181    /// assert_eq!(resolver.level(), 0);
1182    ///
1183    /// // pop from empty resolver does nothing
1184    /// resolver.pop();
1185    /// assert_eq!(resolver.level(), 0);
1186    /// ```
1187    ///
1188    /// [`push`]: Self::push
1189    /// [`pop`]: Self::pop
1190    pub const fn level(&self) -> u16 {
1191        self.nesting_level
1192    }
1193}
1194
1195////////////////////////////////////////////////////////////////////////////////////////////////////
1196
1197/// Iterator on the current declared namespace bindings. Returns pairs of the _(prefix, namespace)_.
1198///
1199/// See [`NamespaceResolver::bindings`] for documentation.
1200#[derive(Debug, Clone)]
1201pub struct NamespaceBindingsIter<'a> {
1202    resolver: &'a NamespaceResolver,
1203    cursor: usize,
1204}
1205
1206impl<'a> Iterator for NamespaceBindingsIter<'a> {
1207    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1208
1209    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1210        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1211            self.cursor += 1; // We increment for next read
1212
1213            // We check if the key has not been overridden by having a look
1214            // at the namespaces declared after in the array
1215            let prefix = binding.prefix(&self.resolver.buffer);
1216            if self.resolver.bindings[self.cursor..]
1217                .iter()
1218                .any(|ne| prefix == ne.prefix(&self.resolver.buffer))
1219            {
1220                continue; // Overridden
1221            }
1222            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1223                let prefix = match prefix {
1224                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1225                    None => PrefixDeclaration::Default,
1226                };
1227                return Some((prefix, namespace));
1228            }
1229        }
1230        None // We have exhausted the array
1231    }
1232
1233    fn size_hint(&self) -> (usize, Option<usize>) {
1234        // Real count could be less if some namespaces was overridden
1235        (0, Some(self.resolver.bindings.len() - self.cursor))
1236    }
1237}
1238
1239impl<'a> FusedIterator for NamespaceBindingsIter<'a> {}
1240
1241/// Iterator on the declared namespace bindings on specified level. Returns pairs of the _(prefix, namespace)_.
1242///
1243/// See [`NamespaceResolver::bindings_of`] for documentation.
1244#[derive(Debug, Clone)]
1245pub struct NamespaceBindingsOfLevelIter<'a> {
1246    resolver: &'a NamespaceResolver,
1247    cursor: usize,
1248    level: u16,
1249}
1250
1251impl<'a> Iterator for NamespaceBindingsOfLevelIter<'a> {
1252    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
1253
1254    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
1255        while let Some(binding) = self.resolver.bindings.get(self.cursor) {
1256            self.cursor += 1; // We increment for next read
1257            if binding.level < self.level {
1258                continue;
1259            }
1260            if binding.level > self.level {
1261                break;
1262            }
1263
1264            if let ResolveResult::Bound(namespace) = binding.namespace(&self.resolver.buffer) {
1265                let prefix = match binding.prefix(&self.resolver.buffer) {
1266                    Some(Prefix(prefix)) => PrefixDeclaration::Named(prefix),
1267                    None => PrefixDeclaration::Default,
1268                };
1269                return Some((prefix, namespace));
1270            }
1271        }
1272        None // We have exhausted the array
1273    }
1274
1275    fn size_hint(&self) -> (usize, Option<usize>) {
1276        // Real count could be less
1277        (0, Some(self.resolver.bindings.len() - self.cursor))
1278    }
1279}
1280
1281impl<'a> FusedIterator for NamespaceBindingsOfLevelIter<'a> {}
1282
1283////////////////////////////////////////////////////////////////////////////////////////////////////
1284
1285#[cfg(test)]
1286mod namespaces {
1287    use super::*;
1288    use ResolveResult::*;
1289    use pretty_assertions::assert_eq;
1290
1291    /// Regression test for <https://github.com/tafia/quick-xml/issues/970>: a single element with
1292    /// many `xmlns:*` declarations must be rejected once the total binding count exceeds the limit.
1293    #[test]
1294    fn rejects_too_many_bindings_on_single_element() {
1295        let limit = DEFAULT_MAX_NAMESPACE_BINDINGS;
1296
1297        // One more than the limit triggers the error.
1298        let mut tag = String::from("e");
1299        for i in 0..=limit {
1300            tag.push_str(&format!(" xmlns:p{}=''", i));
1301        }
1302        let mut resolver = NamespaceResolver::default();
1303        assert_eq!(
1304            resolver.push(&BytesStart::from_content(&tag, 1)),
1305            Err(NamespaceError::TooManyBindings(limit)),
1306        );
1307
1308        // Exactly at the limit is accepted.
1309        let mut tag = String::from("e");
1310        for i in 0..limit {
1311            tag.push_str(&format!(" xmlns:p{}=''", i));
1312        }
1313        let mut resolver = NamespaceResolver::default();
1314        assert_eq!(resolver.push(&BytesStart::from_content(&tag, 1)), Ok(()));
1315
1316        // The limit is configurable, and `usize::MAX` disables it.
1317        let mut resolver = NamespaceResolver::default();
1318        resolver.set_max_namespace_bindings(2);
1319        assert_eq!(
1320            resolver.push(&BytesStart::from_content(
1321                "e xmlns:a='' xmlns:b='' xmlns:c=''",
1322                1,
1323            )),
1324            Err(NamespaceError::TooManyBindings(2)),
1325        );
1326        let mut resolver = NamespaceResolver::default();
1327        resolver.set_max_namespace_bindings(usize::MAX);
1328        assert_eq!(
1329            resolver.push(&BytesStart::from_content(
1330                "e xmlns:a='' xmlns:b='' xmlns:c=''",
1331                1,
1332            )),
1333            Ok(()),
1334        );
1335    }
1336
1337    /// Regression test for <https://github.com/tafia/quick-xml/issues/980>:
1338    /// deeply nested documents where each level declares one `xmlns:*`
1339    /// binding must be rejected once the total binding count exceeds the
1340    /// limit, preventing O(depth²) CPU exhaustion in `resolve_prefix`.
1341    #[test]
1342    fn rejects_too_many_bindings_across_elements() {
1343        let limit = 10;
1344        let mut resolver = NamespaceResolver::default();
1345        resolver.set_max_namespace_bindings(limit);
1346
1347        // Push elements, each declaring one new namespace binding.
1348        for i in 0..limit {
1349            let tag = format!("e xmlns:p{}='ns{}'", i, i);
1350            assert_eq!(
1351                resolver.push(&BytesStart::from_content(&tag, 1)),
1352                Ok(()),
1353                "push {} should succeed",
1354                i,
1355            );
1356        }
1357
1358        // The next binding (on a new element) exceeds the limit.
1359        assert_eq!(
1360            resolver.push(&BytesStart::from_content("e xmlns:extra='ns'", 1)),
1361            Err(NamespaceError::TooManyBindings(limit)),
1362        );
1363
1364        // An element without namespace declarations is still fine.
1365        assert_eq!(resolver.push(&BytesStart::from_content("e", 1)), Ok(()),);
1366    }
1367
1368    /// Popping scopes makes room for new bindings under the limit.
1369    #[test]
1370    fn popping_frees_room_for_bindings() {
1371        let limit = 10;
1372        let mut resolver = NamespaceResolver::default();
1373        resolver.set_max_namespace_bindings(limit);
1374
1375        // Fill to the limit.
1376        for i in 0..limit {
1377            let tag = format!("e xmlns:p{}='ns{}'", i, i);
1378            resolver.push(&BytesStart::from_content(&tag, 1)).unwrap();
1379        }
1380
1381        // Pop the last element's scope — frees one binding slot.
1382        resolver.pop();
1383
1384        // Now a new binding fits.
1385        assert_eq!(
1386            resolver.push(&BytesStart::from_content("e xmlns:new='ns'", 1)),
1387            Ok(()),
1388        );
1389    }
1390
1391    /// Regression test for <https://github.com/tafia/quick-xml/issues/977>:
1392    /// `push()` previously incremented a `u16` depth counter with an unguarded
1393    /// `+= 1`, so a document nested past `u16::MAX` panicked under
1394    /// `overflow-checks` or silently wrapped the counter and corrupted namespace
1395    /// scoping in release. It now returns `TooDeeplyNested` at the boundary.
1396    #[test]
1397    fn push_rejects_pathological_nesting_depth() {
1398        let mut resolver = NamespaceResolver::default();
1399        let tag = BytesStart::from_content("a", 1);
1400        // `u16::MAX` successful pushes, then the next is rejected cleanly.
1401        for _ in 0..u16::MAX {
1402            assert_eq!(resolver.push(&tag), Ok(()));
1403        }
1404        assert_eq!(
1405            resolver.push(&tag),
1406            Err(NamespaceError::TooDeeplyNested(u16::MAX as usize)),
1407        );
1408    }
1409
1410    /// Unprefixed attribute names (resolved with `false` flag) never have a namespace
1411    /// according to <https://www.w3.org/TR/xml-names11/#defaulting>:
1412    ///
1413    /// > A default namespace declaration applies to all unprefixed element names
1414    /// > within its scope. Default namespace declarations do not apply directly
1415    /// > to attribute names; the interpretation of unprefixed attributes is
1416    /// > determined by the element on which they appear.
1417    mod unprefixed {
1418        use super::*;
1419        use pretty_assertions::assert_eq;
1420
1421        /// Basic tests that checks that basic resolver functionality is working
1422        #[test]
1423        fn basic() {
1424            let name = QName("simple");
1425            let ns = Namespace("default");
1426
1427            let mut resolver = NamespaceResolver::default();
1428            let s = resolver.buffer.len();
1429
1430            resolver
1431                .push(&BytesStart::from_content(" xmlns='default'", 0))
1432                .unwrap();
1433            assert_eq!(&resolver.buffer[s..], "default");
1434
1435            // Check that tags without namespaces does not change result
1436            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1437            assert_eq!(&resolver.buffer[s..], "default");
1438            resolver.pop();
1439
1440            assert_eq!(&resolver.buffer[s..], "default");
1441            assert_eq!(
1442                resolver.resolve(name, true),
1443                (Bound(ns), LocalName("simple"))
1444            );
1445            assert_eq!(
1446                resolver.resolve(name, false),
1447                (Unbound, LocalName("simple"))
1448            );
1449        }
1450
1451        /// Test adding a second level of namespaces, which replaces the previous binding
1452        #[test]
1453        fn override_namespace() {
1454            let name = QName("simple");
1455            let old_ns = Namespace("old");
1456            let new_ns = Namespace("new");
1457
1458            let mut resolver = NamespaceResolver::default();
1459            let s = resolver.buffer.len();
1460
1461            resolver
1462                .push(&BytesStart::from_content(" xmlns='old'", 0))
1463                .unwrap();
1464            resolver
1465                .push(&BytesStart::from_content(" xmlns='new'", 0))
1466                .unwrap();
1467
1468            assert_eq!(&resolver.buffer[s..], "oldnew");
1469            assert_eq!(
1470                resolver.resolve(name, true),
1471                (Bound(new_ns), LocalName("simple"))
1472            );
1473            assert_eq!(
1474                resolver.resolve(name, false),
1475                (Unbound, LocalName("simple"))
1476            );
1477
1478            resolver.pop();
1479            assert_eq!(&resolver.buffer[s..], "old");
1480            assert_eq!(
1481                resolver.resolve(name, true),
1482                (Bound(old_ns), LocalName("simple"))
1483            );
1484            assert_eq!(
1485                resolver.resolve(name, false),
1486                (Unbound, LocalName("simple"))
1487            );
1488        }
1489
1490        /// Test adding a second level of namespaces, which reset the previous binding
1491        /// to not bound state by specifying an empty namespace name.
1492        ///
1493        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1494        #[test]
1495        fn reset() {
1496            let name = QName("simple");
1497            let old_ns = Namespace("old");
1498
1499            let mut resolver = NamespaceResolver::default();
1500            let s = resolver.buffer.len();
1501
1502            resolver
1503                .push(&BytesStart::from_content(" xmlns='old'", 0))
1504                .unwrap();
1505            resolver
1506                .push(&BytesStart::from_content(" xmlns=''", 0))
1507                .unwrap();
1508
1509            assert_eq!(&resolver.buffer[s..], "old");
1510            assert_eq!(resolver.resolve(name, true), (Unbound, LocalName("simple")));
1511            assert_eq!(
1512                resolver.resolve(name, false),
1513                (Unbound, LocalName("simple"))
1514            );
1515
1516            resolver.pop();
1517            assert_eq!(&resolver.buffer[s..], "old");
1518            assert_eq!(
1519                resolver.resolve(name, true),
1520                (Bound(old_ns), LocalName("simple"))
1521            );
1522            assert_eq!(
1523                resolver.resolve(name, false),
1524                (Unbound, LocalName("simple"))
1525            );
1526        }
1527    }
1528
1529    mod declared_prefix {
1530        use super::*;
1531        use pretty_assertions::assert_eq;
1532
1533        /// Basic tests that checks that basic resolver functionality is working
1534        #[test]
1535        fn basic() {
1536            let name = QName("p:with-declared-prefix");
1537            let ns = Namespace("default");
1538
1539            let mut resolver = NamespaceResolver::default();
1540            let s = resolver.buffer.len();
1541
1542            resolver
1543                .push(&BytesStart::from_content(" xmlns:p='default'", 0))
1544                .unwrap();
1545            assert_eq!(&resolver.buffer[s..], "pdefault");
1546
1547            // Check that tags without namespaces does not change result
1548            resolver.push(&BytesStart::from_content("", 0)).unwrap();
1549            assert_eq!(&resolver.buffer[s..], "pdefault");
1550            resolver.pop();
1551
1552            assert_eq!(&resolver.buffer[s..], "pdefault");
1553            assert_eq!(
1554                resolver.resolve(name, true),
1555                (Bound(ns), LocalName("with-declared-prefix"))
1556            );
1557            assert_eq!(
1558                resolver.resolve(name, false),
1559                (Bound(ns), LocalName("with-declared-prefix"))
1560            );
1561        }
1562
1563        /// Test adding a second level of namespaces, which replaces the previous binding
1564        #[test]
1565        fn override_namespace() {
1566            let name = QName("p:with-declared-prefix");
1567            let old_ns = Namespace("old");
1568            let new_ns = Namespace("new");
1569
1570            let mut resolver = NamespaceResolver::default();
1571            let s = resolver.buffer.len();
1572
1573            resolver
1574                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1575                .unwrap();
1576            resolver
1577                .push(&BytesStart::from_content(" xmlns:p='new'", 0))
1578                .unwrap();
1579
1580            assert_eq!(&resolver.buffer[s..], "poldpnew");
1581            assert_eq!(
1582                resolver.resolve(name, true),
1583                (Bound(new_ns), LocalName("with-declared-prefix"))
1584            );
1585            assert_eq!(
1586                resolver.resolve(name, false),
1587                (Bound(new_ns), LocalName("with-declared-prefix"))
1588            );
1589
1590            resolver.pop();
1591            assert_eq!(&resolver.buffer[s..], "pold");
1592            assert_eq!(
1593                resolver.resolve(name, true),
1594                (Bound(old_ns), LocalName("with-declared-prefix"))
1595            );
1596            assert_eq!(
1597                resolver.resolve(name, false),
1598                (Bound(old_ns), LocalName("with-declared-prefix"))
1599            );
1600        }
1601
1602        /// Test adding a second level of namespaces, which reset the previous binding
1603        /// to not bound state by specifying an empty namespace name.
1604        ///
1605        /// See <https://www.w3.org/TR/xml-names11/#scoping>
1606        #[test]
1607        fn reset() {
1608            let name = QName("p:with-declared-prefix");
1609            let old_ns = Namespace("old");
1610
1611            let mut resolver = NamespaceResolver::default();
1612            let s = resolver.buffer.len();
1613
1614            resolver
1615                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
1616                .unwrap();
1617            resolver
1618                .push(&BytesStart::from_content(" xmlns:p=''", 0))
1619                .unwrap();
1620
1621            assert_eq!(&resolver.buffer[s..], "poldp");
1622            assert_eq!(
1623                resolver.resolve(name, true),
1624                (Unknown("p".to_string()), LocalName("with-declared-prefix"))
1625            );
1626            assert_eq!(
1627                resolver.resolve(name, false),
1628                (Unknown("p".to_string()), LocalName("with-declared-prefix"))
1629            );
1630
1631            resolver.pop();
1632            assert_eq!(&resolver.buffer[s..], "pold");
1633            assert_eq!(
1634                resolver.resolve(name, true),
1635                (Bound(old_ns), LocalName("with-declared-prefix"))
1636            );
1637            assert_eq!(
1638                resolver.resolve(name, false),
1639                (Bound(old_ns), LocalName("with-declared-prefix"))
1640            );
1641        }
1642    }
1643
1644    /// Tests for `xml` and `xmlns` built-in prefixes.
1645    ///
1646    /// See <https://www.w3.org/TR/xml-names11/#xmlReserved>
1647    mod builtin_prefixes {
1648        use super::*;
1649
1650        mod xml {
1651            use super::*;
1652            use pretty_assertions::assert_eq;
1653
1654            /// `xml` prefix are always defined, it is not required to define it explicitly.
1655            #[test]
1656            fn undeclared() {
1657                let name = QName("xml:random");
1658                let namespace = RESERVED_NAMESPACE_XML.1;
1659
1660                let resolver = NamespaceResolver::default();
1661
1662                assert_eq!(
1663                    resolver.resolve(name, true),
1664                    (Bound(namespace), LocalName("random"))
1665                );
1666
1667                assert_eq!(
1668                    resolver.resolve(name, false),
1669                    (Bound(namespace), LocalName("random"))
1670                );
1671            }
1672
1673            /// `xml` prefix can be declared but it must be bound to the value
1674            /// `http://www.w3.org/XML/1998/namespace`
1675            #[test]
1676            fn rebound_to_correct_ns() {
1677                let mut resolver = NamespaceResolver::default();
1678                let s = resolver.buffer.len();
1679                resolver.push(
1680                    &BytesStart::from_content(
1681                        " xmlns:xml='http://www.w3.org/XML/1998/namespace'",
1682                        0,
1683                    ),
1684                ).expect("`xml` prefix should be possible to bound to `http://www.w3.org/XML/1998/namespace`");
1685                assert_eq!(&resolver.buffer[s..], "");
1686            }
1687
1688            /// `xml` prefix cannot be re-declared to another namespace
1689            #[test]
1690            fn rebound_to_incorrect_ns() {
1691                let mut resolver = NamespaceResolver::default();
1692                let s = resolver.buffer.len();
1693                assert_eq!(
1694                    resolver.push(&BytesStart::from_content(
1695                        " xmlns:xml='not_correct_namespace'",
1696                        0,
1697                    )),
1698                    Err(NamespaceError::InvalidXmlPrefixBind(
1699                        "not_correct_namespace".to_string()
1700                    )),
1701                );
1702                assert_eq!(&resolver.buffer[s..], "");
1703            }
1704
1705            /// `xml` prefix cannot be unbound
1706            #[test]
1707            fn unbound() {
1708                let mut resolver = NamespaceResolver::default();
1709                let s = resolver.buffer.len();
1710                assert_eq!(
1711                    resolver.push(&BytesStart::from_content(" xmlns:xml=''", 0)),
1712                    Err(NamespaceError::InvalidXmlPrefixBind("".to_string())),
1713                );
1714                assert_eq!(&resolver.buffer[s..], "");
1715            }
1716
1717            /// Other prefix cannot be bound to `xml` namespace
1718            #[test]
1719            fn other_prefix_bound_to_xml_namespace() {
1720                let mut resolver = NamespaceResolver::default();
1721                let s = resolver.buffer.len();
1722                assert_eq!(
1723                    resolver.push(&BytesStart::from_content(
1724                        " xmlns:not_xml='http://www.w3.org/XML/1998/namespace'",
1725                        0,
1726                    )),
1727                    Err(NamespaceError::InvalidPrefixForXml("not_xml".to_string())),
1728                );
1729                assert_eq!(&resolver.buffer[s..], "");
1730            }
1731        }
1732
1733        mod xmlns {
1734            use super::*;
1735            use pretty_assertions::assert_eq;
1736
1737            /// `xmlns` prefix are always defined, it is forbidden to define it explicitly
1738            #[test]
1739            fn undeclared() {
1740                let name = QName("xmlns:random");
1741                let namespace = RESERVED_NAMESPACE_XMLNS.1;
1742
1743                let resolver = NamespaceResolver::default();
1744
1745                assert_eq!(
1746                    resolver.resolve(name, true),
1747                    (Bound(namespace), LocalName("random"))
1748                );
1749
1750                assert_eq!(
1751                    resolver.resolve(name, false),
1752                    (Bound(namespace), LocalName("random"))
1753                );
1754            }
1755
1756            /// `xmlns` prefix cannot be re-declared event to its own namespace
1757            #[test]
1758            fn rebound_to_correct_ns() {
1759                let mut resolver = NamespaceResolver::default();
1760                let s = resolver.buffer.len();
1761                assert_eq!(
1762                    resolver.push(&BytesStart::from_content(
1763                        " xmlns:xmlns='http://www.w3.org/2000/xmlns/'",
1764                        0,
1765                    )),
1766                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1767                        "http://www.w3.org/2000/xmlns/".to_string()
1768                    )),
1769                );
1770                assert_eq!(&resolver.buffer[s..], "");
1771            }
1772
1773            /// `xmlns` prefix cannot be re-declared
1774            #[test]
1775            fn rebound_to_incorrect_ns() {
1776                let mut resolver = NamespaceResolver::default();
1777                let s = resolver.buffer.len();
1778                assert_eq!(
1779                    resolver.push(&BytesStart::from_content(
1780                        " xmlns:xmlns='not_correct_namespace'",
1781                        0,
1782                    )),
1783                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1784                        "not_correct_namespace".to_string()
1785                    )),
1786                );
1787                assert_eq!(&resolver.buffer[s..], "");
1788            }
1789
1790            /// `xmlns` prefix cannot be unbound
1791            #[test]
1792            fn unbound() {
1793                let mut resolver = NamespaceResolver::default();
1794                let s = resolver.buffer.len();
1795                assert_eq!(
1796                    resolver.push(&BytesStart::from_content(" xmlns:xmlns=''", 0)),
1797                    Err(NamespaceError::InvalidXmlnsPrefixBind("".to_string())),
1798                );
1799                assert_eq!(&resolver.buffer[s..], "");
1800            }
1801
1802            /// Other prefix cannot be bound to `xmlns` namespace
1803            #[test]
1804            fn other_prefix_bound_to_xmlns_namespace() {
1805                let mut resolver = NamespaceResolver::default();
1806                let s = resolver.buffer.len();
1807                assert_eq!(
1808                    resolver.push(&BytesStart::from_content(
1809                        " xmlns:not_xmlns='http://www.w3.org/2000/xmlns/'",
1810                        0,
1811                    )),
1812                    Err(NamespaceError::InvalidPrefixForXmlns(
1813                        "not_xmlns".to_string()
1814                    )),
1815                );
1816                assert_eq!(&resolver.buffer[s..], "");
1817            }
1818        }
1819    }
1820
1821    #[test]
1822    fn undeclared_prefix() {
1823        let name = QName("unknown:prefix");
1824
1825        let resolver = NamespaceResolver::default();
1826
1827        assert_eq!(
1828            resolver.buffer,
1829            "xmlhttp://www.w3.org/XML/1998/namespacexmlnshttp://www.w3.org/2000/xmlns/"
1830        );
1831        assert_eq!(
1832            resolver.resolve(name, true),
1833            (Unknown("unknown".to_string()), LocalName("prefix"))
1834        );
1835        assert_eq!(
1836            resolver.resolve(name, false),
1837            (Unknown("unknown".to_string()), LocalName("prefix"))
1838        );
1839    }
1840
1841    /// Checks how the QName is decomposed to a prefix and a local name
1842    #[test]
1843    fn prefix_and_local_name() {
1844        let name = QName("foo:bus");
1845        assert_eq!(name.prefix(), Some(Prefix("foo")));
1846        assert_eq!(name.local_name(), LocalName("bus"));
1847        assert_eq!(name.decompose(), (LocalName("bus"), Some(Prefix("foo"))));
1848
1849        let name = QName("foo:");
1850        assert_eq!(name.prefix(), Some(Prefix("foo")));
1851        assert_eq!(name.local_name(), LocalName(""));
1852        assert_eq!(name.decompose(), (LocalName(""), Some(Prefix("foo"))));
1853
1854        let name = QName(":foo");
1855        assert_eq!(name.prefix(), Some(Prefix("")));
1856        assert_eq!(name.local_name(), LocalName("foo"));
1857        assert_eq!(name.decompose(), (LocalName("foo"), Some(Prefix(""))));
1858
1859        let name = QName("foo:bus:baz");
1860        assert_eq!(name.prefix(), Some(Prefix("foo")));
1861        assert_eq!(name.local_name(), LocalName("bus:baz"));
1862        assert_eq!(
1863            name.decompose(),
1864            (LocalName("bus:baz"), Some(Prefix("foo")))
1865        );
1866    }
1867}