Skip to content

Commit eddfbc3

Browse files
committed
Don't load external entity from xmlSAX2GetEntity
Despite the comment, I can't see a reason why external entities must be loaded in the SAX handler. For external entities, the handler is typically first invoked via xmlParseReference which will later load the entity on its own if it wasn't loaded yet. The old code also lead to duplicated SAX events which makes it basically impossible to reuse xmlSAX2GetEntity for a custom SAX parser. See the change to the expected test output. Note that xmlSAX2GetEntity was loading the entity via xmlParseCtxtExternalEntity while xmlParseReference uses xmlParseExternalEntityPrivate. In the previous commit, the two functions were merged, trying to compensate for some slight differences between the two mostly identical implementations. But the more urgent reason for this change is that xmlParseReference has the facility to abort early when recursive entities are detected, avoiding what could practically amount to an infinite loop. If you want to backport this change, note that the previous three commits are required as well: f9ea1a2 Fix copying of entities in xmlParseReference 5c7e0a9 Copy some XMLReader option flags to parser context 1a3e584 Merge code paths loading external entities Found by OSS-Fuzz.
1 parent 1a3e584 commit eddfbc3

File tree

2 files changed

+0
-37
lines changed

2 files changed

+0
-37
lines changed

SAX2.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -590,36 +590,6 @@ xmlSAX2GetEntity(void *ctx, const xmlChar *name)
590590
} else {
591591
ret = xmlGetDocEntity(ctxt->myDoc, name);
592592
}
593-
if ((ret != NULL) &&
594-
((ctxt->validate) || (ctxt->replaceEntities)) &&
595-
(ret->children == NULL) &&
596-
(ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
597-
int val;
598-
599-
/*
600-
* for validation purposes we really need to fetch and
601-
* parse the external entity
602-
*/
603-
xmlNodePtr children;
604-
unsigned long oldnbent = ctxt->nbentities;
605-
606-
val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
607-
ret->ExternalID, &children);
608-
if (val == 0) {
609-
xmlAddChildList((xmlNodePtr) ret, children);
610-
} else {
611-
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
612-
"Failure to process entity %s\n", name, NULL);
613-
ctxt->validate = 0;
614-
return(NULL);
615-
}
616-
ret->owner = 1;
617-
if (ret->checked == 0) {
618-
ret->checked = (ctxt->nbentities - oldnbent + 1) * 2;
619-
if ((ret->content != NULL) && (xmlStrchr(ret->content, '<')))
620-
ret->checked |= 1;
621-
}
622-
}
623593
return(ret);
624594
}
625595

result/noent/ent2.sax2

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,6 @@ SAX.characters(my title, 8)
1717
SAX.endElementNs(title, NULL, NULL)
1818
SAX.characters(
1919
, 1)
20-
SAX.ignorableWhitespace(
21-
, 1)
22-
SAX.startElementNs(title, NULL, NULL, 0, 0, 0)
23-
SAX.characters(my title, 8)
24-
SAX.endElementNs(title, NULL, NULL)
25-
SAX.characters(
26-
, 1)
2720
SAX.characters(
2821
This text is about XML, the, 31)
2922
SAX.getEntity(xml)

0 commit comments

Comments
 (0)