Skip to content

Commit ae29937

Browse files
committed
parser: Make undeclared entities in XML content fatal
When parsing XML content with functions like xmlParseBalancedChunk or xmlParseInNodeContext, make undeclared entities always a fatal error to match 2.13 behavior. This was deliberately changed in 4f329dc, probably to make the tests pass. Should fix #895.
1 parent e4a275a commit ae29937

File tree

3 files changed

+63
-7
lines changed

3 files changed

+63
-7
lines changed

parser.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12368,13 +12368,6 @@ xmlCtxtParseContent(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
1236812368
{
1236912369
xmlCtxtInitializeLate(ctxt);
1237012370

12371-
/*
12372-
* This hack lowers the error level of undeclared entities
12373-
* from XML_ERR_FATAL (well-formedness error) to XML_ERR_ERROR
12374-
* or XML_ERR_WARNING.
12375-
*/
12376-
ctxt->hasExternalSubset = 1;
12377-
1237812371
/*
1237912372
* initialize the SAX2 namespaces stack
1238012373
*/

runtest.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,6 +2355,14 @@ testParseContent(xmlParserCtxtPtr ctxt, xmlDocPtr doc, const char *filename) {
23552355
char *content, *roundTrip;
23562356
int ret = 0;
23572357

2358+
/*
2359+
* Undeclared entities aren't a fatal error if there's an
2360+
* external DTD. When parsing content, we assume there's no
2361+
* DTD, so the undeclared entity test would fail.
2362+
*/
2363+
if (strcmp(filename, "./test/undeclared-entity.xml") == 0)
2364+
return 0;
2365+
23582366
if (ctxt->html) {
23592367
xmlNodePtr cur;
23602368

testparser.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717

1818
#include <string.h>
1919

20+
#ifdef LIBXML_SAX1_ENABLED
21+
static void
22+
ignoreError(void *ctxt ATTRIBUTE_UNUSED,
23+
const xmlError *error ATTRIBUTE_UNUSED) {
24+
}
25+
#endif
26+
2027
static int
2128
testNewDocNode(void) {
2229
xmlNodePtr node;
@@ -128,6 +135,53 @@ testCFileIO(void) {
128135
return err;
129136
}
130137

138+
/*
139+
* The exact rules when undeclared entities are a fatal error
140+
* depend on some conditions that aren't recovered from the
141+
* context document when parsing XML content. This test case
142+
* demonstrates such an asymmetry.
143+
*/
144+
static int
145+
testUndeclEntInContent(void) {
146+
const char xml[] = "<!DOCTYPE doc SYSTEM 'my.dtd'><doc>&undecl;</doc>";
147+
const char content[] = "<doc>&undecl;</doc>";
148+
xmlDocPtr doc;
149+
xmlNodePtr root, list;
150+
int options = XML_PARSE_NOENT | XML_PARSE_NOERROR;
151+
int err = 0;
152+
int res;
153+
154+
/* Parsing the document succeeds because of the external DTD. */
155+
doc = xmlReadDoc(BAD_CAST xml, NULL, NULL, options);
156+
root = xmlDocGetRootElement(doc);
157+
158+
/* Parsing content fails. */
159+
160+
res = xmlParseInNodeContext(root, content, sizeof(content) - 1, options,
161+
&list);
162+
if (res != XML_ERR_UNDECLARED_ENTITY || list != NULL) {
163+
fprintf(stderr, "Wrong result from xmlParseInNodeContext\n");
164+
err = 1;
165+
}
166+
xmlFreeNodeList(list);
167+
168+
#ifdef LIBXML_SAX1_ENABLED
169+
xmlSetStructuredErrorFunc(NULL, ignoreError);
170+
res = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, BAD_CAST content,
171+
&list);
172+
if (res != XML_ERR_UNDECLARED_ENTITY || list != NULL) {
173+
fprintf(stderr, "Wrong result from xmlParseBalancedChunkMemory\n");
174+
err = 1;
175+
}
176+
xmlFreeNodeList(list);
177+
xmlSetStructuredErrorFunc(NULL, NULL);
178+
#endif /* LIBXML_SAX1_ENABLED */
179+
180+
xmlFreeDoc(doc);
181+
182+
return err;
183+
}
184+
131185
#ifdef LIBXML_VALID_ENABLED
132186
static void
133187
testSwitchDtdExtSubset(void *vctxt, const xmlChar *name ATTRIBUTE_UNUSED,
@@ -1195,6 +1249,7 @@ main(void) {
11951249
err |= testUnsupportedEncoding();
11961250
err |= testNodeGetContent();
11971251
err |= testCFileIO();
1252+
err |= testUndeclEntInContent();
11981253
#ifdef LIBXML_VALID_ENABLED
11991254
err |= testSwitchDtd();
12001255
#endif

0 commit comments

Comments
 (0)