@@ -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