@@ -600,7 +600,7 @@ static int dom_xml_serialize_attribute_node_value(xmlOutputBufferPtr out, xmlAtt
600
600
/* These steps are from the attribute serialization algorithm's well-formed checks.
601
601
* Note that this does not return a boolean but an int to be compatible with the TRY/TRY_CLEANUP interface
602
602
* that we do for compatibility with libxml's interfaces. */
603
- static zend_always_inline int dom_xml_check_xmlns_attribute_requirements (const xmlAttr * attr )
603
+ static zend_always_inline int dom_xml_check_xmlns_attribute_requirements (const xmlAttr * attr , const xmlChar * candidate_prefix )
604
604
{
605
605
const xmlChar * attr_value = dom_get_attribute_value (attr );
606
606
@@ -609,8 +609,9 @@ static zend_always_inline int dom_xml_check_xmlns_attribute_requirements(const x
609
609
return -1 ;
610
610
}
611
611
612
- /* 3.5.2.3. If the require well-formed flag is set and the value of attr's value attribute is the empty string */
613
- if (* attr_value == '\0' ) {
612
+ /* 3.5.2.3. If the require well-formed flag is set and the value of attr's value attribute is the empty string.
613
+ * Errata: an "xmlns" attribute is allowed but not one with a prefix, so the idea in the spec is right but the description isn't. */
614
+ if (* attr_value == '\0' && candidate_prefix != NULL ) {
614
615
return -1 ;
615
616
}
616
617
@@ -790,15 +791,16 @@ static int dom_xml_serialize_attributes(
790
791
}
791
792
}
792
793
793
- if (require_well_formed ) {
794
- /* 3.5.2.2 and 3.5.2.3 are done by this call. */
795
- TRY_OR_CLEANUP (dom_xml_check_xmlns_attribute_requirements (attr ));
796
- }
797
-
798
794
/* 3.5.2.4. the attr's prefix matches the string "xmlns", then let candidate prefix be the string "xmlns". */
799
795
if (attr -> ns -> prefix != NULL && strcmp ((const char * ) attr -> ns -> prefix , "xmlns" ) == 0 ) {
800
796
candidate_prefix = BAD_CAST "xmlns" ;
801
797
}
798
+
799
+ /* Errata: step 3.5.2.3 can only really be checked if we already know the candidate prefix. */
800
+ if (require_well_formed ) {
801
+ /* 3.5.2.2 and 3.5.2.3 are done by this call. */
802
+ TRY_OR_CLEANUP (dom_xml_check_xmlns_attribute_requirements (attr , candidate_prefix ));
803
+ }
802
804
}
803
805
/* 3.5.3. Otherwise, the attribute namespace in not the XMLNS namespace. Run these steps: */
804
806
else if (candidate_prefix == NULL ) { /* https://github.com/w3c/DOM-Parsing/issues/29 */
0 commit comments