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;
8use crate::utils::write_byte_string;
9use memchr::memchr;
10use std::fmt::{self, Debug, Formatter};
11
12/// Some namespace was invalid
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum NamespaceError {
15    /// Specified namespace prefix is unknown, cannot resolve namespace for it
16    UnknownPrefix(Vec<u8>),
17    /// Attempts to bind the `xml` prefix to something other than `http://www.w3.org/XML/1998/namespace`.
18    ///
19    /// `xml` prefix can be bound only to `http://www.w3.org/XML/1998/namespace`.
20    ///
21    /// Contains the namespace to which `xml` tried to be bound.
22    InvalidXmlPrefixBind(Vec<u8>),
23    /// Attempts to bind the `xmlns` prefix.
24    ///
25    /// `xmlns` prefix is always bound to `http://www.w3.org/2000/xmlns/` and cannot be bound
26    /// to any other namespace or even to `http://www.w3.org/2000/xmlns/`.
27    ///
28    /// Contains the namespace to which `xmlns` tried to be bound.
29    InvalidXmlnsPrefixBind(Vec<u8>),
30    /// Attempts to bind some prefix (except `xml`) to `http://www.w3.org/XML/1998/namespace`.
31    ///
32    /// Only `xml` prefix can be bound to `http://www.w3.org/XML/1998/namespace`.
33    ///
34    /// Contains the prefix that is tried to be bound.
35    InvalidPrefixForXml(Vec<u8>),
36    /// Attempts to bind some prefix to `http://www.w3.org/2000/xmlns/`.
37    ///
38    /// `http://www.w3.org/2000/xmlns/` cannot be bound to any prefix, even to `xmlns`.
39    ///
40    /// Contains the prefix that is tried to be bound.
41    InvalidPrefixForXmlns(Vec<u8>),
42}
43
44impl fmt::Display for NamespaceError {
45    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46        match self {
47            Self::UnknownPrefix(prefix) => {
48                f.write_str("unknown namespace prefix '")?;
49                write_byte_string(f, prefix)?;
50                f.write_str("'")
51            }
52            Self::InvalidXmlPrefixBind(namespace) => {
53                f.write_str("the namespace prefix 'xml' cannot be bound to '")?;
54                write_byte_string(f, namespace)?;
55                f.write_str("'")
56            }
57            Self::InvalidXmlnsPrefixBind(namespace) => {
58                f.write_str("the namespace prefix 'xmlns' cannot be bound to '")?;
59                write_byte_string(f, namespace)?;
60                f.write_str("'")
61            }
62            Self::InvalidPrefixForXml(prefix) => {
63                f.write_str("the namespace prefix '")?;
64                write_byte_string(f, prefix)?;
65                f.write_str("' cannot be bound to 'http://www.w3.org/XML/1998/namespace'")
66            }
67            Self::InvalidPrefixForXmlns(prefix) => {
68                f.write_str("the namespace prefix '")?;
69                write_byte_string(f, prefix)?;
70                f.write_str("' cannot be bound to 'http://www.w3.org/2000/xmlns/'")
71            }
72        }
73    }
74}
75
76impl std::error::Error for NamespaceError {}
77
78////////////////////////////////////////////////////////////////////////////////////////////////////
79
80/// A [qualified name] of an element or an attribute, including an optional
81/// namespace [prefix](Prefix) and a [local name](LocalName).
82///
83/// [qualified name]: https://www.w3.org/TR/xml-names11/#dt-qualname
84#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
85#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
86pub struct QName<'a>(pub &'a [u8]);
87impl<'a> QName<'a> {
88    /// Converts this name to an internal slice representation.
89    #[inline(always)]
90    pub const fn into_inner(self) -> &'a [u8] {
91        self.0
92    }
93
94    /// Returns local part of this qualified name.
95    ///
96    /// All content up to and including the first `:` character is removed from
97    /// the tag name.
98    ///
99    /// # Examples
100    ///
101    /// ```
102    /// # use quick_xml::name::QName;
103    /// let simple = QName(b"simple-name");
104    /// assert_eq!(simple.local_name().as_ref(), b"simple-name");
105    ///
106    /// let qname = QName(b"namespace:simple-name");
107    /// assert_eq!(qname.local_name().as_ref(), b"simple-name");
108    /// ```
109    pub fn local_name(&self) -> LocalName<'a> {
110        LocalName(self.index().map_or(self.0, |i| &self.0[i + 1..]))
111    }
112
113    /// Returns namespace part of this qualified name or `None` if namespace part
114    /// is not defined (symbol `':'` not found).
115    ///
116    /// # Examples
117    ///
118    /// ```
119    /// # use std::convert::AsRef;
120    /// # use quick_xml::name::QName;
121    /// let simple = QName(b"simple-name");
122    /// assert_eq!(simple.prefix(), None);
123    ///
124    /// let qname = QName(b"prefix:simple-name");
125    /// assert_eq!(qname.prefix().as_ref().map(|n| n.as_ref()), Some(b"prefix".as_ref()));
126    /// ```
127    pub fn prefix(&self) -> Option<Prefix<'a>> {
128        self.index().map(|i| Prefix(&self.0[..i]))
129    }
130
131    /// The same as `(qname.local_name(), qname.prefix())`, but does only one
132    /// lookup for a `':'` symbol.
133    pub fn decompose(&self) -> (LocalName<'a>, Option<Prefix<'a>>) {
134        match self.index() {
135            None => (LocalName(self.0), None),
136            Some(i) => (LocalName(&self.0[i + 1..]), Some(Prefix(&self.0[..i]))),
137        }
138    }
139
140    /// If that `QName` represents `"xmlns"` series of names, returns `Some`,
141    /// otherwise `None` is returned.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// # use quick_xml::name::{QName, PrefixDeclaration};
147    /// let qname = QName(b"xmlns");
148    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Default));
149    ///
150    /// let qname = QName(b"xmlns:prefix");
151    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"prefix")));
152    ///
153    /// // Be aware that this method does not check the validity of the prefix - it can be empty!
154    /// let qname = QName(b"xmlns:");
155    /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"")));
156    ///
157    /// let qname = QName(b"other-name");
158    /// assert_eq!(qname.as_namespace_binding(), None);
159    ///
160    /// // https://www.w3.org/TR/xml-names11/#xmlReserved
161    /// let qname = QName(b"xmlns-reserved-name");
162    /// assert_eq!(qname.as_namespace_binding(), None);
163    /// ```
164    pub fn as_namespace_binding(&self) -> Option<PrefixDeclaration<'a>> {
165        if self.0.starts_with(b"xmlns") {
166            return match self.0.get(5) {
167                None => Some(PrefixDeclaration::Default),
168                Some(&b':') => Some(PrefixDeclaration::Named(&self.0[6..])),
169                _ => None,
170            };
171        }
172        None
173    }
174
175    /// Returns the index in the name where prefix ended
176    #[inline(always)]
177    fn index(&self) -> Option<usize> {
178        memchr(b':', self.0)
179    }
180}
181impl<'a> Debug for QName<'a> {
182    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
183        write!(f, "QName(")?;
184        write_byte_string(f, self.0)?;
185        write!(f, ")")
186    }
187}
188impl<'a> AsRef<[u8]> for QName<'a> {
189    #[inline]
190    fn as_ref(&self) -> &[u8] {
191        self.0
192    }
193}
194
195////////////////////////////////////////////////////////////////////////////////////////////////////
196
197/// A [local (unqualified) name] of an element or an attribute, i.e. a name
198/// without [prefix](Prefix).
199///
200/// [local (unqualified) name]: https://www.w3.org/TR/xml-names11/#dt-localname
201#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
202#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
203pub struct LocalName<'a>(pub(crate) &'a [u8]);
204impl<'a> LocalName<'a> {
205    /// Converts this name to an internal slice representation.
206    #[inline(always)]
207    pub const fn into_inner(self) -> &'a [u8] {
208        self.0
209    }
210}
211impl<'a> Debug for LocalName<'a> {
212    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
213        write!(f, "LocalName(")?;
214        write_byte_string(f, self.0)?;
215        write!(f, ")")
216    }
217}
218impl<'a> AsRef<[u8]> for LocalName<'a> {
219    #[inline]
220    fn as_ref(&self) -> &[u8] {
221        self.0
222    }
223}
224impl<'a> From<QName<'a>> for LocalName<'a> {
225    /// Creates `LocalName` from a [`QName`]
226    ///
227    /// # Examples
228    ///
229    /// ```
230    /// # use quick_xml::name::{LocalName, QName};
231    ///
232    /// let local: LocalName = QName(b"unprefixed").into();
233    /// assert_eq!(local.as_ref(), b"unprefixed");
234    ///
235    /// let local: LocalName = QName(b"some:prefix").into();
236    /// assert_eq!(local.as_ref(), b"prefix");
237    /// ```
238    #[inline]
239    fn from(name: QName<'a>) -> Self {
240        Self(name.index().map_or(name.0, |i| &name.0[i + 1..]))
241    }
242}
243
244////////////////////////////////////////////////////////////////////////////////////////////////////
245
246/// A [namespace prefix] part of the [qualified name](QName) of an element tag
247/// or an attribute: a `prefix` in `<prefix:local-element-name>` or
248/// `prefix:local-attribute-name="attribute value"`.
249///
250/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
251#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
252#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
253pub struct Prefix<'a>(&'a [u8]);
254impl<'a> Prefix<'a> {
255    /// Extracts internal slice
256    #[inline(always)]
257    pub const fn into_inner(self) -> &'a [u8] {
258        self.0
259    }
260
261    /// Checks if this prefix is a special prefix `xml`.
262    #[inline(always)]
263    pub const fn is_xml(&self) -> bool {
264        matches!(self.0, b"xml")
265    }
266
267    /// Checks if this prefix is a special prefix `xmlns`.
268    #[inline(always)]
269    pub const fn is_xmlns(&self) -> bool {
270        matches!(self.0, b"xmlns")
271    }
272}
273impl<'a> Debug for Prefix<'a> {
274    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
275        write!(f, "Prefix(")?;
276        write_byte_string(f, self.0)?;
277        write!(f, ")")
278    }
279}
280impl<'a> AsRef<[u8]> for Prefix<'a> {
281    #[inline]
282    fn as_ref(&self) -> &[u8] {
283        self.0
284    }
285}
286
287////////////////////////////////////////////////////////////////////////////////////////////////////
288
289/// A namespace prefix declaration, `xmlns` or `xmlns:<name>`, as defined in
290/// [XML Schema specification](https://www.w3.org/TR/xml-names11/#ns-decl)
291#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
292pub enum PrefixDeclaration<'a> {
293    /// XML attribute binds a default namespace. Corresponds to `xmlns` in `xmlns="..."`
294    Default,
295    /// XML attribute binds a specified prefix to a namespace. Corresponds to a
296    /// `prefix` in `xmlns:prefix="..."`, which is stored as payload of this variant.
297    Named(&'a [u8]),
298}
299
300////////////////////////////////////////////////////////////////////////////////////////////////////
301
302/// A [namespace name] that is declared in a `xmlns[:prefix]="namespace name"`.
303///
304/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
305#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
306#[cfg_attr(feature = "serde-types", derive(serde::Deserialize, serde::Serialize))]
307pub struct Namespace<'a>(pub &'a [u8]);
308impl<'a> Namespace<'a> {
309    /// Converts this namespace to an internal slice representation.
310    ///
311    /// This is [non-normalized] attribute value, i.e. any entity references is
312    /// not expanded and space characters are not removed. This means, that
313    /// different byte slices, returned from this method, can represent the same
314    /// namespace and would be treated by parser as identical.
315    ///
316    /// For example, if the entity **eacute** has been defined to be **é**,
317    /// the empty tags below all contain namespace declarations binding the
318    /// prefix `p` to the same [IRI reference], `http://example.org/rosé`.
319    ///
320    /// ```xml
321    /// <p:foo xmlns:p="http://example.org/rosé" />
322    /// <p:foo xmlns:p="http://example.org/ros&#xe9;" />
323    /// <p:foo xmlns:p="http://example.org/ros&#xE9;" />
324    /// <p:foo xmlns:p="http://example.org/ros&#233;" />
325    /// <p:foo xmlns:p="http://example.org/ros&eacute;" />
326    /// ```
327    ///
328    /// This is because XML entity references are expanded during attribute value
329    /// normalization.
330    ///
331    /// [non-normalized]: https://www.w3.org/TR/xml11/#AVNormalize
332    /// [IRI reference]: https://datatracker.ietf.org/doc/html/rfc3987
333    #[inline(always)]
334    pub const fn into_inner(self) -> &'a [u8] {
335        self.0
336    }
337    //TODO: implement value normalization and use it when comparing namespaces
338}
339impl<'a> Debug for Namespace<'a> {
340    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
341        write!(f, "Namespace(")?;
342        write_byte_string(f, self.0)?;
343        write!(f, ")")
344    }
345}
346impl<'a> AsRef<[u8]> for Namespace<'a> {
347    #[inline]
348    fn as_ref(&self) -> &[u8] {
349        self.0
350    }
351}
352
353////////////////////////////////////////////////////////////////////////////////////////////////////
354
355/// Result of [prefix] resolution which creates by [`NsReader::resolve_attribute`],
356/// [`NsReader::resolve_element`], [`NsReader::read_resolved_event`] and
357/// [`NsReader::read_resolved_event_into`] methods.
358///
359/// [prefix]: Prefix
360/// [`NsReader::resolve_attribute`]: crate::reader::NsReader::resolve_attribute
361/// [`NsReader::resolve_element`]: crate::reader::NsReader::resolve_element
362/// [`NsReader::read_resolved_event`]: crate::reader::NsReader::read_resolved_event
363/// [`NsReader::read_resolved_event_into`]: crate::reader::NsReader::read_resolved_event_into
364#[derive(Clone, PartialEq, Eq, Hash)]
365pub enum ResolveResult<'ns> {
366    /// Qualified name does not contain prefix, and resolver does not define
367    /// default namespace, so name is not bound to any namespace
368    Unbound,
369    /// [`Prefix`] resolved to the specified namespace
370    Bound(Namespace<'ns>),
371    /// Specified prefix was not found in scope
372    Unknown(Vec<u8>),
373}
374impl<'ns> Debug for ResolveResult<'ns> {
375    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
376        match self {
377            Self::Unbound => write!(f, "Unbound"),
378            Self::Bound(ns) => write!(f, "Bound({:?})", ns),
379            Self::Unknown(p) => {
380                write!(f, "Unknown(")?;
381                write_byte_string(f, p)?;
382                write!(f, ")")
383            }
384        }
385    }
386}
387
388impl<'ns> TryFrom<ResolveResult<'ns>> for Option<Namespace<'ns>> {
389    type Error = NamespaceError;
390
391    /// Try to convert this result to an optional namespace and returns
392    /// [`NamespaceError::UnknownPrefix`] if this result represents unknown prefix
393    fn try_from(result: ResolveResult<'ns>) -> Result<Self, NamespaceError> {
394        use ResolveResult::*;
395
396        match result {
397            Unbound => Ok(None),
398            Bound(ns) => Ok(Some(ns)),
399            Unknown(p) => Err(NamespaceError::UnknownPrefix(p)),
400        }
401    }
402}
403
404////////////////////////////////////////////////////////////////////////////////////////////////////
405
406/// An entry that contains index into the buffer with namespace bindings.
407///
408/// Defines a mapping from *[namespace prefix]* to *[namespace name]*.
409/// If prefix is empty, defines a *default namespace* binding that applies to
410/// unprefixed element names (unprefixed attribute names do not bind to any
411/// namespace and they processing is dependent on the element in which their
412/// defined).
413///
414/// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix
415/// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
416#[derive(Debug, Clone)]
417struct NamespaceEntry {
418    /// Index of the namespace in the buffer
419    start: usize,
420    /// Length of the prefix
421    /// * if greater than zero, then binds this namespace to the slice
422    ///   `[start..start + prefix_len]` in the buffer.
423    /// * else defines the current default namespace.
424    prefix_len: usize,
425    /// The length of a namespace name (the URI) of this namespace declaration.
426    /// Name started just after prefix and extend for `value_len` bytes.
427    ///
428    /// The XML standard [specifies] that an empty namespace value 'removes' a namespace declaration
429    /// for the extent of its scope. For prefix declarations that's not very interesting, but it is
430    /// vital for default namespace declarations. With `xmlns=""` you can revert back to the default
431    /// behaviour of leaving unqualified element names unqualified.
432    ///
433    /// [specifies]: https://www.w3.org/TR/xml-names11/#scoping
434    value_len: usize,
435    /// Level of nesting at which this namespace was declared. The declaring element is included,
436    /// i.e., a declaration on the document root has `level = 1`.
437    /// This is used to pop the namespace when the element gets closed.
438    level: i32,
439}
440
441impl NamespaceEntry {
442    /// Get the namespace prefix, bound to this namespace declaration, or `None`,
443    /// if this declaration is for default namespace (`xmlns="..."`).
444    #[inline]
445    fn prefix<'b>(&self, ns_buffer: &'b [u8]) -> Option<Prefix<'b>> {
446        if self.prefix_len == 0 {
447            None
448        } else {
449            Some(Prefix(&ns_buffer[self.start..self.start + self.prefix_len]))
450        }
451    }
452
453    /// Gets the namespace name (the URI) slice out of namespace buffer
454    ///
455    /// Returns `None` if namespace for this prefix was explicitly removed from
456    /// scope, using `xmlns[:prefix]=""`
457    #[inline]
458    fn namespace<'ns>(&self, buffer: &'ns [u8]) -> ResolveResult<'ns> {
459        if self.value_len == 0 {
460            ResolveResult::Unbound
461        } else {
462            let start = self.start + self.prefix_len;
463            ResolveResult::Bound(Namespace(&buffer[start..start + self.value_len]))
464        }
465    }
466}
467
468/// A namespace management buffer.
469///
470/// Holds all internal logic to push/pop namespaces with their levels.
471#[derive(Debug, Clone)]
472pub(crate) struct NamespaceResolver {
473    /// Buffer that contains names of namespace prefixes (the part between `xmlns:`
474    /// and an `=`) and namespace values.
475    buffer: Vec<u8>,
476    /// A stack of namespace bindings to prefixes that currently in scope
477    bindings: Vec<NamespaceEntry>,
478    /// The number of open tags at the moment. We need to keep track of this to know which namespace
479    /// declarations to remove when we encounter an `End` event.
480    nesting_level: i32,
481}
482
483/// That constant define the one of [reserved namespaces] for the xml standard.
484///
485/// The prefix `xml` is by definition bound to the namespace name
486/// `http://www.w3.org/XML/1998/namespace`. It may, but need not, be declared, and must not be
487/// undeclared or bound to any other namespace name. Other prefixes must not be bound to this
488/// namespace name, and it must not be declared as the default namespace.
489///
490/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
491const RESERVED_NAMESPACE_XML: (Prefix, Namespace) = (
492    Prefix(b"xml"),
493    Namespace(b"http://www.w3.org/XML/1998/namespace"),
494);
495/// That constant define the one of [reserved namespaces] for the xml standard.
496///
497/// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
498/// to the namespace name `http://www.w3.org/2000/xmlns/`. It must not be declared or
499/// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
500///  declared as the default namespace. Element names must not have the prefix `xmlns`.
501///
502/// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
503const RESERVED_NAMESPACE_XMLNS: (Prefix, Namespace) = (
504    Prefix(b"xmlns"),
505    Namespace(b"http://www.w3.org/2000/xmlns/"),
506);
507
508impl Default for NamespaceResolver {
509    fn default() -> Self {
510        let mut buffer = Vec::new();
511        let mut bindings = Vec::new();
512        for ent in &[RESERVED_NAMESPACE_XML, RESERVED_NAMESPACE_XMLNS] {
513            let prefix = ent.0.into_inner();
514            let uri = ent.1.into_inner();
515            bindings.push(NamespaceEntry {
516                start: buffer.len(),
517                prefix_len: prefix.len(),
518                value_len: uri.len(),
519                level: 0,
520            });
521            buffer.extend(prefix);
522            buffer.extend(uri);
523        }
524
525        Self {
526            buffer,
527            bindings,
528            nesting_level: 0,
529        }
530    }
531}
532
533impl NamespaceResolver {
534    /// Begins a new scope and add to it all [namespace bindings] that found in
535    /// the specified start element.
536    ///
537    /// [namespace binding]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
538    pub fn push(&mut self, start: &BytesStart) -> Result<(), NamespaceError> {
539        self.nesting_level += 1;
540        let level = self.nesting_level;
541        // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns'
542        // (default namespace) attribute.
543        for a in start.attributes().with_checks(false) {
544            if let Ok(Attribute { key: k, value: v }) = a {
545                match k.as_namespace_binding() {
546                    Some(PrefixDeclaration::Default) => {
547                        let start = self.buffer.len();
548                        self.buffer.extend_from_slice(&v);
549                        self.bindings.push(NamespaceEntry {
550                            start,
551                            prefix_len: 0,
552                            value_len: v.len(),
553                            level,
554                        });
555                    }
556                    Some(PrefixDeclaration::Named(b"xml")) => {
557                        if Namespace(&v) != RESERVED_NAMESPACE_XML.1 {
558                            // error, `xml` prefix explicitly set to different value
559                            return Err(NamespaceError::InvalidXmlPrefixBind(v.to_vec()));
560                        }
561                        // don't add another NamespaceEntry for the `xml` namespace prefix
562                    }
563                    Some(PrefixDeclaration::Named(b"xmlns")) => {
564                        // error, `xmlns` prefix explicitly set
565                        return Err(NamespaceError::InvalidXmlnsPrefixBind(v.to_vec()));
566                    }
567                    Some(PrefixDeclaration::Named(prefix)) => {
568                        let ns = Namespace(&v);
569
570                        if ns == RESERVED_NAMESPACE_XML.1 {
571                            // error, non-`xml` prefix set to xml uri
572                            return Err(NamespaceError::InvalidPrefixForXml(prefix.to_vec()));
573                        } else if ns == RESERVED_NAMESPACE_XMLNS.1 {
574                            // error, non-`xmlns` prefix set to xmlns uri
575                            return Err(NamespaceError::InvalidPrefixForXmlns(prefix.to_vec()));
576                        }
577
578                        let start = self.buffer.len();
579                        self.buffer.extend_from_slice(prefix);
580                        self.buffer.extend_from_slice(&v);
581                        self.bindings.push(NamespaceEntry {
582                            start,
583                            prefix_len: prefix.len(),
584                            value_len: v.len(),
585                            level,
586                        });
587                    }
588                    None => {}
589                }
590            } else {
591                break;
592            }
593        }
594        Ok(())
595    }
596
597    /// Ends a top-most scope by popping all [namespace binding], that was added by
598    /// last call to [`Self::push()`].
599    ///
600    /// [namespace binding]: https://www.w3.org/TR/xml-names11/#dt-NSDecl
601    pub fn pop(&mut self) {
602        self.nesting_level -= 1;
603        let current_level = self.nesting_level;
604        // from the back (most deeply nested scope), look for the first scope that is still valid
605        match self.bindings.iter().rposition(|n| n.level <= current_level) {
606            // none of the namespaces are valid, remove all of them
607            None => {
608                self.buffer.clear();
609                self.bindings.clear();
610            }
611            // drop all namespaces past the last valid namespace
612            Some(last_valid_pos) => {
613                if let Some(len) = self.bindings.get(last_valid_pos + 1).map(|n| n.start) {
614                    self.buffer.truncate(len);
615                    self.bindings.truncate(last_valid_pos + 1);
616                }
617            }
618        }
619    }
620
621    /// Resolves a potentially qualified **element name** or **attribute name**
622    /// into (namespace name, local name).
623    ///
624    /// *Qualified* names have the form `prefix:local-name` where the `prefix` is
625    /// defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
626    /// The namespace prefix can be defined on the same element as the element or
627    /// attribute in question.
628    ///
629    /// *Unqualified* attribute names do *not* inherit the current *default namespace*.
630    ///
631    /// # Lifetimes
632    ///
633    /// - `'n`: lifetime of an attribute or an element name
634    #[inline]
635    pub fn resolve<'n>(
636        &self,
637        name: QName<'n>,
638        use_default: bool,
639    ) -> (ResolveResult, LocalName<'n>) {
640        let (local_name, prefix) = name.decompose();
641        (self.resolve_prefix(prefix, use_default), local_name)
642    }
643
644    /// Finds a [namespace name] for a given qualified **element name**, borrow
645    /// it from the internal buffer.
646    ///
647    /// Returns `None`, if:
648    /// - name is unqualified
649    /// - prefix not found in the current scope
650    /// - prefix was [unbound] using `xmlns:prefix=""`
651    ///
652    /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName
653    /// [unbound]: https://www.w3.org/TR/xml-names11/#scoping
654    #[inline]
655    pub fn find(&self, element_name: QName) -> ResolveResult {
656        self.resolve_prefix(element_name.prefix(), true)
657    }
658
659    fn resolve_prefix(&self, prefix: Option<Prefix>, use_default: bool) -> ResolveResult {
660        self.bindings
661            .iter()
662            // Find the last defined binding that corresponds to the given prefix
663            .rev()
664            .find_map(|n| match (n.prefix(&self.buffer), prefix) {
665                // This is default namespace definition and name has no explicit prefix
666                (None, None) if use_default => Some(n.namespace(&self.buffer)),
667                (None, None) => Some(ResolveResult::Unbound),
668
669                // One part has prefix but other is not -> skip
670                (None, Some(_)) => None,
671                (Some(_), None) => None,
672
673                // Prefixes does not match -> skip
674                (Some(definition), Some(usage)) if definition != usage => None,
675
676                // Prefixes the same, entry defines binding reset (corresponds to `xmlns:p=""`)
677                _ if n.value_len == 0 => Some(Self::maybe_unknown(prefix)),
678                // Prefixes the same, returns corresponding namespace
679                _ => Some(n.namespace(&self.buffer)),
680            })
681            .unwrap_or_else(|| Self::maybe_unknown(prefix))
682    }
683
684    #[inline]
685    fn maybe_unknown(prefix: Option<Prefix>) -> ResolveResult<'static> {
686        match prefix {
687            Some(p) => ResolveResult::Unknown(p.into_inner().to_vec()),
688            None => ResolveResult::Unbound,
689        }
690    }
691
692    #[inline]
693    pub const fn iter(&self) -> PrefixIter {
694        PrefixIter {
695            resolver: self,
696            // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns:
697            bindings_cursor: 2,
698        }
699    }
700}
701
702////////////////////////////////////////////////////////////////////////////////////////////////////
703
704/// Iterator on the current declared prefixes.
705///
706/// See [`NsReader::prefixes`](crate::NsReader::prefixes) for documentation.
707#[derive(Debug, Clone)]
708pub struct PrefixIter<'a> {
709    resolver: &'a NamespaceResolver,
710    bindings_cursor: usize,
711}
712
713impl<'a> Iterator for PrefixIter<'a> {
714    type Item = (PrefixDeclaration<'a>, Namespace<'a>);
715
716    fn next(&mut self) -> Option<(PrefixDeclaration<'a>, Namespace<'a>)> {
717        while let Some(namespace_entry) = self.resolver.bindings.get(self.bindings_cursor) {
718            self.bindings_cursor += 1; // We increment for next read
719
720            // We check if the key has not been overridden by having a look
721            // at the namespaces declared after in the array
722            let prefix = namespace_entry.prefix(&self.resolver.buffer);
723            if self.resolver.bindings[self.bindings_cursor..]
724                .iter()
725                .any(|ne| prefix == ne.prefix(&self.resolver.buffer))
726            {
727                continue; // Overridden
728            }
729            let namespace = if let ResolveResult::Bound(namespace) =
730                namespace_entry.namespace(&self.resolver.buffer)
731            {
732                namespace
733            } else {
734                continue; // We don't return unbound namespaces
735            };
736            let prefix = if let Some(Prefix(prefix)) = prefix {
737                PrefixDeclaration::Named(prefix)
738            } else {
739                PrefixDeclaration::Default
740            };
741            return Some((prefix, namespace));
742        }
743        None // We have exhausted the array
744    }
745
746    fn size_hint(&self) -> (usize, Option<usize>) {
747        // Real count could be less if some namespaces was overridden
748        (0, Some(self.resolver.bindings.len() - self.bindings_cursor))
749    }
750}
751
752#[cfg(test)]
753mod namespaces {
754    use super::*;
755    use pretty_assertions::assert_eq;
756    use ResolveResult::*;
757
758    /// Unprefixed attribute names (resolved with `false` flag) never have a namespace
759    /// according to <https://www.w3.org/TR/xml-names11/#defaulting>:
760    ///
761    /// > A default namespace declaration applies to all unprefixed element names
762    /// > within its scope. Default namespace declarations do not apply directly
763    /// > to attribute names; the interpretation of unprefixed attributes is
764    /// > determined by the element on which they appear.
765    mod unprefixed {
766        use super::*;
767        use pretty_assertions::assert_eq;
768
769        /// Basic tests that checks that basic resolver functionality is working
770        #[test]
771        fn basic() {
772            let name = QName(b"simple");
773            let ns = Namespace(b"default");
774
775            let mut resolver = NamespaceResolver::default();
776            let s = resolver.buffer.len();
777
778            resolver
779                .push(&BytesStart::from_content(" xmlns='default'", 0))
780                .unwrap();
781            assert_eq!(&resolver.buffer[s..], b"default");
782
783            // Check that tags without namespaces does not change result
784            resolver.push(&BytesStart::from_content("", 0)).unwrap();
785            assert_eq!(&resolver.buffer[s..], b"default");
786            resolver.pop();
787
788            assert_eq!(&resolver.buffer[s..], b"default");
789            assert_eq!(
790                resolver.resolve(name, true),
791                (Bound(ns), LocalName(b"simple"))
792            );
793            assert_eq!(
794                resolver.resolve(name, false),
795                (Unbound, LocalName(b"simple"))
796            );
797            assert_eq!(resolver.find(name), Bound(ns));
798        }
799
800        /// Test adding a second level of namespaces, which replaces the previous binding
801        #[test]
802        fn override_namespace() {
803            let name = QName(b"simple");
804            let old_ns = Namespace(b"old");
805            let new_ns = Namespace(b"new");
806
807            let mut resolver = NamespaceResolver::default();
808            let s = resolver.buffer.len();
809
810            resolver
811                .push(&BytesStart::from_content(" xmlns='old'", 0))
812                .unwrap();
813            resolver
814                .push(&BytesStart::from_content(" xmlns='new'", 0))
815                .unwrap();
816
817            assert_eq!(&resolver.buffer[s..], b"oldnew");
818            assert_eq!(
819                resolver.resolve(name, true),
820                (Bound(new_ns), LocalName(b"simple"))
821            );
822            assert_eq!(
823                resolver.resolve(name, false),
824                (Unbound, LocalName(b"simple"))
825            );
826            assert_eq!(resolver.find(name), Bound(new_ns));
827
828            resolver.pop();
829            assert_eq!(&resolver.buffer[s..], b"old");
830            assert_eq!(
831                resolver.resolve(name, true),
832                (Bound(old_ns), LocalName(b"simple"))
833            );
834            assert_eq!(
835                resolver.resolve(name, false),
836                (Unbound, LocalName(b"simple"))
837            );
838            assert_eq!(resolver.find(name), Bound(old_ns));
839        }
840
841        /// Test adding a second level of namespaces, which reset the previous binding
842        /// to not bound state by specifying an empty namespace name.
843        ///
844        /// See <https://www.w3.org/TR/xml-names11/#scoping>
845        #[test]
846        fn reset() {
847            let name = QName(b"simple");
848            let old_ns = Namespace(b"old");
849
850            let mut resolver = NamespaceResolver::default();
851            let s = resolver.buffer.len();
852
853            resolver
854                .push(&BytesStart::from_content(" xmlns='old'", 0))
855                .unwrap();
856            resolver
857                .push(&BytesStart::from_content(" xmlns=''", 0))
858                .unwrap();
859
860            assert_eq!(&resolver.buffer[s..], b"old");
861            assert_eq!(
862                resolver.resolve(name, true),
863                (Unbound, LocalName(b"simple"))
864            );
865            assert_eq!(
866                resolver.resolve(name, false),
867                (Unbound, LocalName(b"simple"))
868            );
869            assert_eq!(resolver.find(name), Unbound);
870
871            resolver.pop();
872            assert_eq!(&resolver.buffer[s..], b"old");
873            assert_eq!(
874                resolver.resolve(name, true),
875                (Bound(old_ns), LocalName(b"simple"))
876            );
877            assert_eq!(
878                resolver.resolve(name, false),
879                (Unbound, LocalName(b"simple"))
880            );
881            assert_eq!(resolver.find(name), Bound(old_ns));
882        }
883    }
884
885    mod declared_prefix {
886        use super::*;
887        use pretty_assertions::assert_eq;
888
889        /// Basic tests that checks that basic resolver functionality is working
890        #[test]
891        fn basic() {
892            let name = QName(b"p:with-declared-prefix");
893            let ns = Namespace(b"default");
894
895            let mut resolver = NamespaceResolver::default();
896            let s = resolver.buffer.len();
897
898            resolver
899                .push(&BytesStart::from_content(" xmlns:p='default'", 0))
900                .unwrap();
901            assert_eq!(&resolver.buffer[s..], b"pdefault");
902
903            // Check that tags without namespaces does not change result
904            resolver.push(&BytesStart::from_content("", 0)).unwrap();
905            assert_eq!(&resolver.buffer[s..], b"pdefault");
906            resolver.pop();
907
908            assert_eq!(&resolver.buffer[s..], b"pdefault");
909            assert_eq!(
910                resolver.resolve(name, true),
911                (Bound(ns), LocalName(b"with-declared-prefix"))
912            );
913            assert_eq!(
914                resolver.resolve(name, false),
915                (Bound(ns), LocalName(b"with-declared-prefix"))
916            );
917            assert_eq!(resolver.find(name), Bound(ns));
918        }
919
920        /// Test adding a second level of namespaces, which replaces the previous binding
921        #[test]
922        fn override_namespace() {
923            let name = QName(b"p:with-declared-prefix");
924            let old_ns = Namespace(b"old");
925            let new_ns = Namespace(b"new");
926
927            let mut resolver = NamespaceResolver::default();
928            let s = resolver.buffer.len();
929
930            resolver
931                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
932                .unwrap();
933            resolver
934                .push(&BytesStart::from_content(" xmlns:p='new'", 0))
935                .unwrap();
936
937            assert_eq!(&resolver.buffer[s..], b"poldpnew");
938            assert_eq!(
939                resolver.resolve(name, true),
940                (Bound(new_ns), LocalName(b"with-declared-prefix"))
941            );
942            assert_eq!(
943                resolver.resolve(name, false),
944                (Bound(new_ns), LocalName(b"with-declared-prefix"))
945            );
946            assert_eq!(resolver.find(name), Bound(new_ns));
947
948            resolver.pop();
949            assert_eq!(&resolver.buffer[s..], b"pold");
950            assert_eq!(
951                resolver.resolve(name, true),
952                (Bound(old_ns), LocalName(b"with-declared-prefix"))
953            );
954            assert_eq!(
955                resolver.resolve(name, false),
956                (Bound(old_ns), LocalName(b"with-declared-prefix"))
957            );
958            assert_eq!(resolver.find(name), Bound(old_ns));
959        }
960
961        /// Test adding a second level of namespaces, which reset the previous binding
962        /// to not bound state by specifying an empty namespace name.
963        ///
964        /// See <https://www.w3.org/TR/xml-names11/#scoping>
965        #[test]
966        fn reset() {
967            let name = QName(b"p:with-declared-prefix");
968            let old_ns = Namespace(b"old");
969
970            let mut resolver = NamespaceResolver::default();
971            let s = resolver.buffer.len();
972
973            resolver
974                .push(&BytesStart::from_content(" xmlns:p='old'", 0))
975                .unwrap();
976            resolver
977                .push(&BytesStart::from_content(" xmlns:p=''", 0))
978                .unwrap();
979
980            assert_eq!(&resolver.buffer[s..], b"poldp");
981            assert_eq!(
982                resolver.resolve(name, true),
983                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
984            );
985            assert_eq!(
986                resolver.resolve(name, false),
987                (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix"))
988            );
989            assert_eq!(resolver.find(name), Unknown(b"p".to_vec()));
990
991            resolver.pop();
992            assert_eq!(&resolver.buffer[s..], b"pold");
993            assert_eq!(
994                resolver.resolve(name, true),
995                (Bound(old_ns), LocalName(b"with-declared-prefix"))
996            );
997            assert_eq!(
998                resolver.resolve(name, false),
999                (Bound(old_ns), LocalName(b"with-declared-prefix"))
1000            );
1001            assert_eq!(resolver.find(name), Bound(old_ns));
1002        }
1003    }
1004
1005    /// Tests for `xml` and `xmlns` built-in prefixes.
1006    ///
1007    /// See <https://www.w3.org/TR/xml-names11/#xmlReserved>
1008    mod builtin_prefixes {
1009        use super::*;
1010
1011        mod xml {
1012            use super::*;
1013            use pretty_assertions::assert_eq;
1014
1015            /// `xml` prefix are always defined, it is not required to define it explicitly.
1016            #[test]
1017            fn undeclared() {
1018                let name = QName(b"xml:random");
1019                let namespace = RESERVED_NAMESPACE_XML.1;
1020
1021                let resolver = NamespaceResolver::default();
1022
1023                assert_eq!(
1024                    resolver.resolve(name, true),
1025                    (Bound(namespace), LocalName(b"random"))
1026                );
1027
1028                assert_eq!(
1029                    resolver.resolve(name, false),
1030                    (Bound(namespace), LocalName(b"random"))
1031                );
1032                assert_eq!(resolver.find(name), Bound(namespace));
1033            }
1034
1035            /// `xml` prefix can be declared but it must be bound to the value
1036            /// `http://www.w3.org/XML/1998/namespace`
1037            #[test]
1038            fn rebound_to_correct_ns() {
1039                let mut resolver = NamespaceResolver::default();
1040                let s = resolver.buffer.len();
1041                resolver.push(
1042                    &BytesStart::from_content(
1043                        " xmlns:xml='http://www.w3.org/XML/1998/namespace'",
1044                        0,
1045                    ),
1046                ).expect("`xml` prefix should be possible to bound to `http://www.w3.org/XML/1998/namespace`");
1047                assert_eq!(&resolver.buffer[s..], b"");
1048            }
1049
1050            /// `xml` prefix cannot be re-declared to another namespace
1051            #[test]
1052            fn rebound_to_incorrect_ns() {
1053                let mut resolver = NamespaceResolver::default();
1054                let s = resolver.buffer.len();
1055                assert_eq!(
1056                    resolver.push(&BytesStart::from_content(
1057                        " xmlns:xml='not_correct_namespace'",
1058                        0,
1059                    )),
1060                    Err(NamespaceError::InvalidXmlPrefixBind(
1061                        b"not_correct_namespace".to_vec()
1062                    )),
1063                );
1064                assert_eq!(&resolver.buffer[s..], b"");
1065            }
1066
1067            /// `xml` prefix cannot be unbound
1068            #[test]
1069            fn unbound() {
1070                let mut resolver = NamespaceResolver::default();
1071                let s = resolver.buffer.len();
1072                assert_eq!(
1073                    resolver.push(&BytesStart::from_content(" xmlns:xml=''", 0)),
1074                    Err(NamespaceError::InvalidXmlPrefixBind(b"".to_vec())),
1075                );
1076                assert_eq!(&resolver.buffer[s..], b"");
1077            }
1078
1079            /// Other prefix cannot be bound to `xml` namespace
1080            #[test]
1081            fn other_prefix_bound_to_xml_namespace() {
1082                let mut resolver = NamespaceResolver::default();
1083                let s = resolver.buffer.len();
1084                assert_eq!(
1085                    resolver.push(&BytesStart::from_content(
1086                        " xmlns:not_xml='http://www.w3.org/XML/1998/namespace'",
1087                        0,
1088                    )),
1089                    Err(NamespaceError::InvalidPrefixForXml(b"not_xml".to_vec())),
1090                );
1091                assert_eq!(&resolver.buffer[s..], b"");
1092            }
1093        }
1094
1095        mod xmlns {
1096            use super::*;
1097            use pretty_assertions::assert_eq;
1098
1099            /// `xmlns` prefix are always defined, it is forbidden to define it explicitly
1100            #[test]
1101            fn undeclared() {
1102                let name = QName(b"xmlns:random");
1103                let namespace = RESERVED_NAMESPACE_XMLNS.1;
1104
1105                let resolver = NamespaceResolver::default();
1106
1107                assert_eq!(
1108                    resolver.resolve(name, true),
1109                    (Bound(namespace), LocalName(b"random"))
1110                );
1111
1112                assert_eq!(
1113                    resolver.resolve(name, false),
1114                    (Bound(namespace), LocalName(b"random"))
1115                );
1116                assert_eq!(resolver.find(name), Bound(namespace));
1117            }
1118
1119            /// `xmlns` prefix cannot be re-declared event to its own namespace
1120            #[test]
1121            fn rebound_to_correct_ns() {
1122                let mut resolver = NamespaceResolver::default();
1123                let s = resolver.buffer.len();
1124                assert_eq!(
1125                    resolver.push(&BytesStart::from_content(
1126                        " xmlns:xmlns='http://www.w3.org/2000/xmlns/'",
1127                        0,
1128                    )),
1129                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1130                        b"http://www.w3.org/2000/xmlns/".to_vec()
1131                    )),
1132                );
1133                assert_eq!(&resolver.buffer[s..], b"");
1134            }
1135
1136            /// `xmlns` prefix cannot be re-declared
1137            #[test]
1138            fn rebound_to_incorrect_ns() {
1139                let mut resolver = NamespaceResolver::default();
1140                let s = resolver.buffer.len();
1141                assert_eq!(
1142                    resolver.push(&BytesStart::from_content(
1143                        " xmlns:xmlns='not_correct_namespace'",
1144                        0,
1145                    )),
1146                    Err(NamespaceError::InvalidXmlnsPrefixBind(
1147                        b"not_correct_namespace".to_vec()
1148                    )),
1149                );
1150                assert_eq!(&resolver.buffer[s..], b"");
1151            }
1152
1153            /// `xmlns` prefix cannot be unbound
1154            #[test]
1155            fn unbound() {
1156                let mut resolver = NamespaceResolver::default();
1157                let s = resolver.buffer.len();
1158                assert_eq!(
1159                    resolver.push(&BytesStart::from_content(" xmlns:xmlns=''", 0)),
1160                    Err(NamespaceError::InvalidXmlnsPrefixBind(b"".to_vec())),
1161                );
1162                assert_eq!(&resolver.buffer[s..], b"");
1163            }
1164
1165            /// Other prefix cannot be bound to `xmlns` namespace
1166            #[test]
1167            fn other_prefix_bound_to_xmlns_namespace() {
1168                let mut resolver = NamespaceResolver::default();
1169                let s = resolver.buffer.len();
1170                assert_eq!(
1171                    resolver.push(&BytesStart::from_content(
1172                        " xmlns:not_xmlns='http://www.w3.org/2000/xmlns/'",
1173                        0,
1174                    )),
1175                    Err(NamespaceError::InvalidPrefixForXmlns(b"not_xmlns".to_vec())),
1176                );
1177                assert_eq!(&resolver.buffer[s..], b"");
1178            }
1179        }
1180    }
1181
1182    #[test]
1183    fn undeclared_prefix() {
1184        let name = QName(b"unknown:prefix");
1185
1186        let resolver = NamespaceResolver::default();
1187
1188        assert_eq!(
1189            resolver.buffer,
1190            b"xmlhttp://www.w3.org/XML/1998/namespacexmlnshttp://www.w3.org/2000/xmlns/"
1191        );
1192        assert_eq!(
1193            resolver.resolve(name, true),
1194            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1195        );
1196        assert_eq!(
1197            resolver.resolve(name, false),
1198            (Unknown(b"unknown".to_vec()), LocalName(b"prefix"))
1199        );
1200        assert_eq!(resolver.find(name), Unknown(b"unknown".to_vec()));
1201    }
1202
1203    /// Checks how the QName is decomposed to a prefix and a local name
1204    #[test]
1205    fn prefix_and_local_name() {
1206        let name = QName(b"foo:bus");
1207        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1208        assert_eq!(name.local_name(), LocalName(b"bus"));
1209        assert_eq!(name.decompose(), (LocalName(b"bus"), Some(Prefix(b"foo"))));
1210
1211        let name = QName(b"foo:");
1212        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1213        assert_eq!(name.local_name(), LocalName(b""));
1214        assert_eq!(name.decompose(), (LocalName(b""), Some(Prefix(b"foo"))));
1215
1216        let name = QName(b":foo");
1217        assert_eq!(name.prefix(), Some(Prefix(b"")));
1218        assert_eq!(name.local_name(), LocalName(b"foo"));
1219        assert_eq!(name.decompose(), (LocalName(b"foo"), Some(Prefix(b""))));
1220
1221        let name = QName(b"foo:bus:baz");
1222        assert_eq!(name.prefix(), Some(Prefix(b"foo")));
1223        assert_eq!(name.local_name(), LocalName(b"bus:baz"));
1224        assert_eq!(
1225            name.decompose(),
1226            (LocalName(b"bus:baz"), Some(Prefix(b"foo")))
1227        );
1228    }
1229}