1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-08-03 08:21:55 +03:00

parser: Always throw entity errors if external DTD is loaded

When parsing with XML_PARSE_DTDLOAD, missing entities are always an
error.

Also consolidate behavior when validating. See b717abdd.
This commit is contained in:
Nick Wellnhofer
2024-05-02 16:23:04 +02:00
parent 39e5b35bd0
commit fdc5ff3657
9 changed files with 38 additions and 57 deletions

View File

@ -7602,11 +7602,22 @@ xmlLookupGeneralEntity(xmlParserCtxtPtr ctxt, const xmlChar *name, int inAttr) {
* standalone='yes'. * standalone='yes'.
*/ */
if (ent == NULL) { if (ent == NULL) {
if ((ctxt->standalone == 1) || if (((!ctxt->validate) && (ctxt->loadsubset)) ||
(ctxt->standalone == 1) ||
((ctxt->hasExternalSubset == 0) && ((ctxt->hasExternalSubset == 0) &&
(ctxt->hasPErefs == 0))) { (ctxt->hasPErefs == 0))) {
xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY, xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
"Entity '%s' not defined\n", name); "Entity '%s' not defined\n", name);
} else if (ctxt->validate) {
/*
* [ VC: Entity Declared ]
* In a document with an external subset or external
* parameter entities with "standalone='no'", ...
* ... The declaration of a parameter entity must
* precede any reference to it...
*/
xmlValidityError(ctxt, XML_ERR_UNDECLARED_ENTITY,
"Entity '%s' not defined\n", name, NULL);
} else { } else {
xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY, xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
"Entity '%s' not defined\n", name, NULL); "Entity '%s' not defined\n", name, NULL);
@ -7823,37 +7834,19 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
(ctxt->sax->getParameterEntity != NULL)) (ctxt->sax->getParameterEntity != NULL))
entity = ctxt->sax->getParameterEntity(ctxt->userData, name); entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
if (entity == NULL) { if (entity == NULL) {
/* if (((!ctxt->validate) && (ctxt->loadsubset)) ||
* [ WFC: Entity Declared ] (ctxt->standalone == 1)) {
* In a document without any DTD, a document with only an
* internal DTD subset which contains no parameter entity
* references, or a document with "standalone='yes'", ...
* ... The declaration of a parameter entity must precede
* any reference to it...
*/
if ((ctxt->standalone == 1) ||
((ctxt->hasExternalSubset == 0) &&
(ctxt->hasPErefs == 0))) {
xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY, xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
"PEReference: %%%s; not found\n", "PEReference: %%%s; not found\n",
name); name);
} else { } else if (ctxt->validate) {
/* xmlValidityError(ctxt, XML_ERR_UNDECLARED_ENTITY,
* [ VC: Entity Declared ] "PEReference: %%%s; not found\n",
* In a document with an external subset or external name, NULL);
* parameter entities with "standalone='no'", ... } else {
* ... The declaration of a parameter entity must xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
* precede any reference to it... "PEReference: %%%s; not found\n",
*/
if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
xmlValidityError(ctxt, XML_ERR_UNDECLARED_ENTITY,
"PEReference: %%%s; not found\n",
name, NULL);
} else
xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
"PEReference: %%%s; not found\n",
name, NULL); name, NULL);
ctxt->valid = 0;
} }
} else { } else {
/* /*
@ -8098,30 +8091,18 @@ xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
(ctxt->sax->getParameterEntity != NULL)) (ctxt->sax->getParameterEntity != NULL))
entity = ctxt->sax->getParameterEntity(ctxt->userData, name); entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
if (entity == NULL) { if (entity == NULL) {
/* if (((!ctxt->validate) && (ctxt->loadsubset)) ||
* [ WFC: Entity Declared ] (ctxt->standalone == 1)) {
* In a document without any DTD, a document with only an
* internal DTD subset which contains no parameter entity
* references, or a document with "standalone='yes'", ...
* ... The declaration of a parameter entity must precede
* any reference to it...
*/
if ((ctxt->standalone == 1) ||
((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY, xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
"PEReference: %%%s; not found\n", name); "PEReference: %%%s; not found\n", name);
} else { } else if (ctxt->validate) {
/* xmlValidityError(ctxt, XML_ERR_UNDECLARED_ENTITY,
* [ VC: Entity Declared ] "PEReference: %%%s; not found\n",
* In a document with an external subset or external name, NULL);
* parameter entities with "standalone='no'", ... } else {
* ... The declaration of a parameter entity must
* precede any reference to it...
*/
xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY, xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
"PEReference: %%%s; not found\n", "PEReference: %%%s; not found\n",
name, NULL); name, NULL);
ctxt->valid = 0;
} }
} else { } else {
/* /*

View File

@ -101,7 +101,7 @@ run_test(desc="Loading entity with custom callback",
exp_status="loaded", exp_err=[ exp_status="loaded", exp_err=[
( 3, 'failed to load "http://example.com/dtds/sample.dtd": Attempt to load network entity\n'), ( 3, 'failed to load "http://example.com/dtds/sample.dtd": Attempt to load network entity\n'),
( -1, "Attempt to load network entity: http://example.com/dtds/sample.dtd"), ( -1, "Attempt to load network entity: http://example.com/dtds/sample.dtd"),
( 3, "Entity 'sample.entity' not defined\n") ( 4, "Entity 'sample.entity' not defined\n")
]) ])
# Register a catalog (also accessible via pystr://) and retry # Register a catalog (also accessible via pystr://) and retry
@ -114,7 +114,7 @@ run_test(desc="Loading entity and unregistering callback",
test_callback=lambda: libxml2.popInputCallbacks(), test_callback=lambda: libxml2.popInputCallbacks(),
exp_status="loaded", exp_err=[ exp_status="loaded", exp_err=[
( 3, "failed to load \"py://strings/dtds/sample.dtd\": No such file or directory\n"), ( 3, "failed to load \"py://strings/dtds/sample.dtd\": No such file or directory\n"),
( 3, "Entity 'sample.entity' not defined\n") ( 4, "Entity 'sample.entity' not defined\n")
]) ])
# Try to load the document again # Try to load the document again

View File

@ -1,4 +1,3 @@
xmlParseDocument returned error 26
SAX.setDocumentLocator() SAX.setDocumentLocator()
SAX.startDocument() SAX.startDocument()
SAX.internalSubset(item, , ) SAX.internalSubset(item, , )

View File

@ -1,4 +1,3 @@
xmlParseDocument returned error 26
SAX.setDocumentLocator() SAX.setDocumentLocator()
SAX.startDocument() SAX.startDocument()
SAX.internalSubset(item, , ) SAX.internalSubset(item, , )

View File

@ -1,4 +1,3 @@
xmlParseDocument returned error 26
SAX.setDocumentLocator() SAX.setDocumentLocator()
SAX.startDocument() SAX.startDocument()
SAX.internalSubset(item, , ) SAX.internalSubset(item, , )

View File

@ -1,4 +1,3 @@
xmlParseDocument returned error 26
SAX.setDocumentLocator() SAX.setDocumentLocator()
SAX.startDocument() SAX.startDocument()
SAX.internalSubset(test, , ) SAX.internalSubset(test, , )

View File

@ -1,4 +1,3 @@
xmlParseDocument returned error 26
SAX.setDocumentLocator() SAX.setDocumentLocator()
SAX.startDocument() SAX.startDocument()
SAX.internalSubset(test, , ) SAX.internalSubset(test, , )

View File

@ -1,4 +1,3 @@
xmlParseDocument returned error 26
SAX.setDocumentLocator() SAX.setDocumentLocator()
SAX.startDocument() SAX.startDocument()
SAX.internalSubset(test, , ) SAX.internalSubset(test, , )

View File

@ -11,6 +11,8 @@
* daniel@veillard.com * daniel@veillard.com
*/ */
#define XML_DEPRECATED
#include "libxml.h" #include "libxml.h"
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
@ -1601,9 +1603,11 @@ oldParseTest(const char *filename, const char *result,
* base of the test, parse with the old API * base of the test, parse with the old API
*/ */
#ifdef LIBXML_SAX1_ENABLED #ifdef LIBXML_SAX1_ENABLED
xmlGetWarningsDefaultValue = 0;
doc = xmlParseFile(filename); doc = xmlParseFile(filename);
xmlGetWarningsDefaultValue = 1;
#else #else
doc = xmlReadFile(filename, NULL, 0); doc = xmlReadFile(filename, NULL, XML_PARSE_NOWARNING);
#endif #endif
if (doc == NULL) if (doc == NULL)
return(1); return(1);
@ -1622,9 +1626,11 @@ oldParseTest(const char *filename, const char *result,
* Parse the saved result to make sure the round trip is okay * Parse the saved result to make sure the round trip is okay
*/ */
#ifdef LIBXML_SAX1_ENABLED #ifdef LIBXML_SAX1_ENABLED
xmlGetWarningsDefaultValue = 0;
doc = xmlParseFile(temp); doc = xmlParseFile(temp);
xmlGetWarningsDefaultValue = 1;
#else #else
doc = xmlReadFile(temp, NULL, 0); doc = xmlReadFile(temp, NULL, XML_PARSE_NOWARNING);
#endif #endif
if (doc == NULL) if (doc == NULL)
return(1); return(1);