@@ -600,7 +600,7 @@ static int dom_xml_serialize_attribute_node_value(xmlOutputBufferPtr out, xmlAtt
600600/* These steps are from the attribute serialization algorithm's well-formed checks.
601601 * Note that this does not return a boolean but an int to be compatible with the TRY/TRY_CLEANUP interface
602602 * 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 )
604604{
605605 const xmlChar * attr_value = dom_get_attribute_value (attr );
606606
@@ -609,8 +609,9 @@ static zend_always_inline int dom_xml_check_xmlns_attribute_requirements(const x
609609 return -1 ;
610610 }
611611
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 ) {
614615 return -1 ;
615616 }
616617
@@ -790,15 +791,16 @@ static int dom_xml_serialize_attributes(
790791 }
791792 }
792793
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-
798794 /* 3.5.2.4. the attr's prefix matches the string "xmlns", then let candidate prefix be the string "xmlns". */
799795 if (attr -> ns -> prefix != NULL && strcmp ((const char * ) attr -> ns -> prefix , "xmlns" ) == 0 ) {
800796 candidate_prefix = BAD_CAST "xmlns" ;
801797 }
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+ }
802804 }
803805 /* 3.5.3. Otherwise, the attribute namespace in not the XMLNS namespace. Run these steps: */
804806 else if (candidate_prefix == NULL ) { /* https://github.com/w3c/DOM-Parsing/issues/29 */
0 commit comments