[More investigation follows. Writing from a different machine, so cannot reply 
to my own 
email]

The issue, brief summary: upgrade of libxml2 from 2.7.6-14.el6 to 
2.7.6-14.el6_5.1 (RHEL6) 
broke the --postvalid/--dtdvalid options.

Minimal test case:

[a.xml]
<?xml version="1.0"?>
<!-- vi: set sw=2 : -->
<!DOCTYPE a SYSTEM "a.dtd">
<a>
 <b/>
</a>


[a.dtd]
<!ELEMENT a (b|c)>
<!ENTITY % base.dtd SYSTEM "b.dtd">
%base.dtd;


[b.dtd]
<!ELEMENT b EMPTY>
<!ELEMENT c EMPTY>

This command works:
xmllint --valid --noout --dtdvalid a.dtd a.xml

This command doesn't:
xmllint --postvalid --noout --dtdvalid a.dtd a.xml
a.xml:5: element b: validity error : No declaration for element b
Document a.xml does not validate against a.dtd

The problem:
1. With --postvalid (and similarly treated options --dtdvalid, --dtdvalidfpi) 
the 
XML_PARSE_DTDVALID is not set. Instead, XML_PARSE_DTDLOAD is set (the 
validation is 
performed after loading of the XML document). Solution: the 
xmlParserHandlePEReference() should also check for XML_PARSE_DTDLOAD or the 
parsed 
entities defined in the nested DTDs will not load.

2. Even with parsed entities loaded, the validation then fails: the 
xmlParserHandlePEReference() is called during the post-validation with the 
ctxt->options 
equal to zero when loading a separate DTD (e.g. due to --dtdvalid option) via 
the 
xmlSAXParseDTD(). Solution: xmlSAXParseDTD() should set the ctxt->options to 
XML_PARSE_DTDLOAD - after all, xmlSAXParseDTD *is* loading the DTD.

3. The comment in the xmlParserHandlePEReference() is an obvious copy-paste: it 
refers 
to parsed entities while the code actually handles parameter entities. 
Solution: fix the 
comment :)

Updated patch attached (against RHEL version of 2.7.6 - will update to git 
version of 
libxml2 if needed).

Regards,
Alexey.
--- a/parser.c	2014-05-20 21:51:44.662586440 -0700
+++ b/parser.c	2014-05-20 21:54:33.239045181 -0700
@@ -2438,8 +2438,8 @@
 		    xmlCharEncoding enc;
 
 		    /*
-		     * Note: external parsed entities will not be loaded, it is
-		     * not required for a non-validating parser, unless the
+		     * Note: external parameter entities will not be loaded, it
+		     * isnot required for a non-validating parser, unless the
 		     * option of validating, or substituting entities were
 		     * given. Doing so is far more secure as the parser will
 		     * only process data coming from the document entity by
@@ -2448,6 +2448,7 @@
                     if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
 		        ((ctxt->options & XML_PARSE_NOENT) == 0) &&
 			((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
+			((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
 			(ctxt->validate == 0))
 			return;
 
@@ -12516,6 +12517,9 @@
 	return(NULL);
     }
 
+    /* We are loading a DTD */
+    ctxt->options = XML_PARSE_DTDLOAD;
+
     /*
      * Set-up the SAX context
      */
_______________________________________________
xml mailing list, project page  http://xmlsoft.org/
xml@gnome.org
https://mail.gnome.org/mailman/listinfo/xml

Reply via email to