1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-10-26 12:25:09 +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'.
*/
if (ent == NULL) {
if ((ctxt->standalone == 1) ||
if (((!ctxt->validate) && (ctxt->loadsubset)) ||
(ctxt->standalone == 1) ||
((ctxt->hasExternalSubset == 0) &&
(ctxt->hasPErefs == 0))) {
xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
"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 {
xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
"Entity '%s' not defined\n", name, NULL);
@ -7823,37 +7834,19 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
(ctxt->sax->getParameterEntity != NULL))
entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
if (entity == NULL) {
/*
* [ WFC: Entity Declared ]
* 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))) {
if (((!ctxt->validate) && (ctxt->loadsubset)) ||
(ctxt->standalone == 1)) {
xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
"PEReference: %%%s; not found\n",
name);
} else {
/*
* [ 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...
*/
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",
} else if (ctxt->validate) {
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);
ctxt->valid = 0;
}
} else {
/*
@ -8098,30 +8091,18 @@ xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
(ctxt->sax->getParameterEntity != NULL))
entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
if (entity == NULL) {
/*
* [ WFC: Entity Declared ]
* 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))) {
if (((!ctxt->validate) && (ctxt->loadsubset)) ||
(ctxt->standalone == 1)) {
xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
"PEReference: %%%s; not found\n", name);
} else {
/*
* [ 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...
*/
} else if (ctxt->validate) {
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);
ctxt->valid = 0;
}
} else {
/*

View File

@ -101,7 +101,7 @@ run_test(desc="Loading entity with custom callback",
exp_status="loaded", exp_err=[
( 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"),
( 3, "Entity 'sample.entity' not defined\n")
( 4, "Entity 'sample.entity' not defined\n")
])
# 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(),
exp_status="loaded", exp_err=[
( 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,6 +11,8 @@
* daniel@veillard.com
*/
#define XML_DEPRECATED
#include "libxml.h"
#include <stdio.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
*/
#ifdef LIBXML_SAX1_ENABLED
xmlGetWarningsDefaultValue = 0;
doc = xmlParseFile(filename);
xmlGetWarningsDefaultValue = 1;
#else
doc = xmlReadFile(filename, NULL, 0);
doc = xmlReadFile(filename, NULL, XML_PARSE_NOWARNING);
#endif
if (doc == NULL)
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
*/
#ifdef LIBXML_SAX1_ENABLED
xmlGetWarningsDefaultValue = 0;
doc = xmlParseFile(temp);
xmlGetWarningsDefaultValue = 1;
#else
doc = xmlReadFile(temp, NULL, 0);
doc = xmlReadFile(temp, NULL, XML_PARSE_NOWARNING);
#endif
if (doc == NULL)
return(1);