parser: More refactoring of entity parsing

Remove xmlCreateEntityParserCtxtInternal.

Rework xmlNewEntityInputStream.
This commit is contained in:
Nick Wellnhofer 2023-12-27 15:50:58 +01:00
parent d3ceea0b5b
commit 24b7144f2c
2 changed files with 40 additions and 149 deletions

126
parser.c
View File

@ -114,11 +114,6 @@ struct _xmlAttrHashBucket {
int index;
};
static xmlParserCtxtPtr
xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
xmlParserCtxtPtr pctx);
static int
xmlParseElementStart(xmlParserCtxtPtr ctxt);
@ -12174,24 +12169,10 @@ xmlCtxtParseEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
/*
* Load entity
*/
if (ent->content != NULL) {
input = xmlNewStringInputStream(ctxt, ent->content);
} else if ((ent->URI != NULL) || (ent->ExternalID != NULL)) {
input = xmlLoadExternalEntity((char *) ent->URI,
(char *) ent->ExternalID, ctxt);
} else {
/* Assume the content is empty */
return(XML_ERR_OK);
}
input = xmlNewEntityInputStream(ctxt, ent);
if (input == NULL)
return(ctxt->errNo);
/*
* Set entity in input stream
*/
input->entity = ent;
/*
* We need to reset the namespace database, so that entities don't
* pick up namespaces from the parent of a reference.
@ -12697,82 +12678,6 @@ xmlParseEntity(const char *filename) {
}
#endif /* LIBXML_SAX1_ENABLED */
/**
* xmlCreateEntityParserCtxtInternal:
* @URL: the entity URL
* @ID: the entity PUBLIC ID
* @base: a possible base for the target URI
* @pctx: parser context used to set options on new context
*
* Create a parser context for an external entity
* Automatic support for ZLIB/Compress compressed document is provided
* by default if found at compile-time.
*
* Returns the new parser context or NULL
*/
static xmlParserCtxtPtr
xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
xmlParserCtxtPtr pctx) {
xmlParserCtxtPtr ctxt;
xmlParserInputPtr inputStream;
xmlChar *uri = NULL;
ctxt = xmlNewSAXParserCtxt(sax, userData);
if (ctxt == NULL) {
xmlErrMemory(pctx);
return(NULL);
}
if (pctx != NULL) {
if (pctx->errorHandler != NULL)
xmlCtxtSetErrorHandler(ctxt, pctx->errorHandler, pctx->errorCtxt);
ctxt->options = pctx->options;
ctxt->_private = pctx->_private;
ctxt->input_id = pctx->input_id;
}
/* Don't read from stdin. */
if (xmlStrcmp(URL, BAD_CAST "-") == 0)
URL = BAD_CAST "./-";
if (base != NULL) {
if (xmlBuildURISafe(URL, base, &uri) < 0) {
xmlErrMemory(ctxt);
goto error;
}
if (uri != NULL)
URL = uri;
}
inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
if (inputStream == NULL)
goto error;
inputPush(ctxt, inputStream);
xmlFree(uri);
return(ctxt);
error:
if (pctx != NULL) {
if (xmlCopyError(&ctxt->lastError, &pctx->lastError) < 0) {
xmlErrMemory(pctx);
} else {
pctx->errNo = ctxt->errNo;
if (ctxt->disableSAX > pctx->disableSAX)
pctx->disableSAX = ctxt->disableSAX;
if (ctxt->wellFormed == 0)
pctx->wellFormed = 0;
}
}
xmlFree(uri);
xmlFreeParserCtxt(ctxt);
return(NULL);
}
/**
* xmlCreateEntityParserCtxt:
* @URL: the entity URL
@ -12788,8 +12693,35 @@ error:
xmlParserCtxtPtr
xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
const xmlChar *base) {
return xmlCreateEntityParserCtxtInternal(NULL, NULL, URL, ID, base, NULL);
xmlParserCtxtPtr ctxt;
xmlParserInputPtr inputStream;
xmlChar *uri = NULL;
ctxt = xmlNewParserCtxt();
if (ctxt == NULL)
return(NULL);
if (base != NULL) {
if (xmlBuildURISafe(URL, base, &uri) < 0)
goto error;
if (uri != NULL)
URL = uri;
}
inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
if (inputStream == NULL)
goto error;
if (inputPush(ctxt, inputStream) < 0)
goto error;
xmlFree(uri);
return(ctxt);
error:
xmlFree(uri);
xmlFreeParserCtxt(ctxt);
return(NULL);
}
/************************************************************************

View File

@ -1509,63 +1509,22 @@ xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
* Returns the new input stream or NULL
*/
xmlParserInputPtr
xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
xmlParserInputPtr input;
if (entity == NULL) {
xmlErrInternal(ctxt, "xmlNewEntityInputStream entity = NULL\n",
NULL);
return(NULL);
}
if (entity->content == NULL) {
switch (entity->etype) {
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
xmlErrInternal(ctxt, "Cannot parse entity %s\n",
entity->name);
break;
case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
case XML_EXTERNAL_PARAMETER_ENTITY:
input = xmlLoadExternalEntity((char *) entity->URI,
(char *) entity->ExternalID, ctxt);
if (input != NULL)
input->entity = entity;
return(input);
case XML_INTERNAL_GENERAL_ENTITY:
xmlErrInternal(ctxt,
"Internal entity %s without content !\n",
entity->name);
break;
case XML_INTERNAL_PARAMETER_ENTITY:
xmlErrInternal(ctxt,
"Internal parameter entity %s without content !\n",
entity->name);
break;
case XML_INTERNAL_PREDEFINED_ENTITY:
xmlErrInternal(ctxt,
"Predefined entity %s without content !\n",
entity->name);
break;
}
if ((ctxt == NULL) || (ent == NULL))
return(NULL);
if (ent->content != NULL) {
input = xmlNewStringInputStream(ctxt, ent->content);
} else if (ent->URI != NULL) {
input = xmlLoadExternalEntity((char *) ent->URI,
(char *) ent->ExternalID, ctxt);
} else {
input = xmlNewStringInputStream(ctxt, "");
}
/*
* We create an input stream with a NULL buffer here and make the
* input pointers reference the entity content directly. This is
* unusual and somewhat dangerous.
*/
input = xmlNewInputStream(ctxt);
if (input == NULL) {
return(NULL);
}
if (entity->URI != NULL)
input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
input->base = entity->content;
if (entity->length == 0)
entity->length = xmlStrlen(entity->content);
input->cur = entity->content;
input->end = &entity->content[entity->length];
input->entity = entity;
input->entity = ent;
return(input);
}