@@ -399,6 +399,24 @@ pub(crate) struct NamespaceResolver {
399
399
nesting_level : i32 ,
400
400
}
401
401
402
+ /// These constants define the reserved namespaces for the xml standard.
403
+ ///
404
+ /// The prefix `xml` is by definition bound to the namespace name
405
+ /// `http://www.w3.org/XML/1998/namespace`. It may, but need not, be declared, and must not be
406
+ /// undeclared or bound to any other namespace name. Other prefixes must not be bound to this
407
+ /// namespace name, and it must not be declared as the default namespace.
408
+ ///
409
+ /// The prefix `xmlns` is used only to declare namespace bindings and is by definition bound
410
+ /// to the namespace name http://www.w3.org/2000/xmlns/. It must not be declared or
411
+ /// undeclared. Other prefixes must not be bound to this namespace name, and it must not be
412
+ /// declared as the default namespace. Element names must not have the prefix xmlns.
413
+ ///
414
+ /// [reserved namespaces]: https://www.w3.org/TR/xml-names11/#xmlReserved
415
+ static WELL_KNOWN_NAMESPACES : & ' static [ [ & str ; 2 ] ] = & [
416
+ [ "xml" , "http://www.w3.org/XML/1998/namespace" ] ,
417
+ [ "xmlns" , "http://www.w3.org/2000/xmlns/" ] ,
418
+ ] ;
419
+
402
420
impl NamespaceResolver {
403
421
/// Begins a new scope and add to it all [namespace bindings] that found in
404
422
/// the specified start element.
@@ -542,7 +560,13 @@ impl NamespaceResolver {
542
560
#[ inline]
543
561
fn maybe_unknown ( prefix : Option < Prefix > ) -> ResolveResult < ' static > {
544
562
match prefix {
545
- Some ( p) => ResolveResult :: Unknown ( p. into_inner ( ) . to_vec ( ) ) ,
563
+ Some ( p) => WELL_KNOWN_NAMESPACES
564
+ . iter ( )
565
+ . find ( |x| p == Prefix ( x[ 0 ] . as_bytes ( ) ) )
566
+ . map_or_else (
567
+ || ResolveResult :: Unknown ( p. into_inner ( ) . to_vec ( ) ) ,
568
+ |[ _, uri] | ResolveResult :: Bound ( Namespace ( uri. as_bytes ( ) ) ) ,
569
+ ) ,
546
570
None => ResolveResult :: Unbound ,
547
571
}
548
572
}
@@ -787,6 +811,63 @@ mod namespaces {
787
811
}
788
812
}
789
813
814
+ mod builtin_prefixes {
815
+ use super :: * ;
816
+ use pretty_assertions:: assert_eq;
817
+
818
+ #[ test]
819
+ fn undeclared_reserved_prefix_xml ( ) {
820
+ let prefix_name = "xml" ;
821
+ let namespace_uri = "http://www.w3.org/XML/1998/namespace" ;
822
+
823
+ let prefix = Prefix ( prefix_name. as_bytes ( ) ) ;
824
+ let namespace = Namespace ( namespace_uri. as_bytes ( ) ) ;
825
+
826
+ let resolver = NamespaceResolver :: default ( ) ;
827
+ let tag = b"random" ;
828
+
829
+ let name_buf = [ prefix. into_inner ( ) , tag] . join ( & b":" [ ..] ) ;
830
+ let name = QName ( & name_buf) ;
831
+
832
+ assert_eq ! (
833
+ resolver. resolve( name, b"" , true ) ,
834
+ ( Bound ( namespace) , LocalName ( tag) )
835
+ ) ;
836
+
837
+ assert_eq ! (
838
+ resolver. resolve( name. clone( ) , b"" , false ) ,
839
+ ( Bound ( namespace) , LocalName ( tag) )
840
+ ) ;
841
+ assert_eq ! ( resolver. find( name. clone( ) , b"" ) , Bound ( namespace) ) ;
842
+ }
843
+
844
+ #[ test]
845
+ fn undeclared_reserved_prefix_xmlns ( ) {
846
+ let prefix_name = "xmlns" ;
847
+ let namespace_uri = "http://www.w3.org/2000/xmlns/" ;
848
+
849
+ let prefix = Prefix ( prefix_name. as_bytes ( ) ) ;
850
+ let namespace = Namespace ( namespace_uri. as_bytes ( ) ) ;
851
+
852
+ let resolver = NamespaceResolver :: default ( ) ;
853
+ let tag = b"random" ;
854
+
855
+ let name_buf = [ prefix. into_inner ( ) , tag] . join ( & b":" [ ..] ) ;
856
+ let name = QName ( & name_buf) ;
857
+
858
+ assert_eq ! (
859
+ resolver. resolve( name, b"" , true ) ,
860
+ ( Bound ( namespace) , LocalName ( tag) )
861
+ ) ;
862
+
863
+ assert_eq ! (
864
+ resolver. resolve( name. clone( ) , b"" , false ) ,
865
+ ( Bound ( namespace) , LocalName ( tag) )
866
+ ) ;
867
+ assert_eq ! ( resolver. find( name. clone( ) , b"" ) , Bound ( namespace) ) ;
868
+ }
869
+ }
870
+
790
871
#[ test]
791
872
fn undeclared_prefix ( ) {
792
873
let name = QName ( b"unknown:prefix" ) ;
0 commit comments