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