[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