parser: Pass resource type to resource loader

This commit is contained in:
Nick Wellnhofer 2024-06-11 19:10:41 +02:00
parent f96dca9c0e
commit 5238404325
11 changed files with 99 additions and 55 deletions

4
SAX2.c
View File

@ -427,8 +427,8 @@ xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId,
if (xmlStrlen(URI) > XML_MAX_URI_LENGTH) { if (xmlStrlen(URI) > XML_MAX_URI_LENGTH) {
xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT, "URI too long"); xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT, "URI too long");
} else { } else {
ret = xmlLoadExternalEntity((const char *) URI, ret = xmlLoadResource(ctxt, (const char *) URI,
(const char *) publicId, ctxt); (const char *) publicId, XML_RESOURCE_DTD);
} }
xmlFree(URI); xmlFree(URI);

View File

@ -404,8 +404,8 @@ xmlFuzzMainEntity(size_t *size) {
int int
xmlFuzzResourceLoader(void *data ATTRIBUTE_UNUSED, const char *URL, xmlFuzzResourceLoader(void *data ATTRIBUTE_UNUSED, const char *URL,
const char *ID ATTRIBUTE_UNUSED, const char *ID ATTRIBUTE_UNUSED,
int type ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, xmlResourceType type ATTRIBUTE_UNUSED,
xmlParserInputPtr *out) { int flags ATTRIBUTE_UNUSED, xmlParserInputPtr *out) {
xmlParserInputPtr input; xmlParserInputPtr input;
xmlFuzzEntityInfo *entity; xmlFuzzEntityInfo *entity;

View File

@ -108,7 +108,7 @@ xmlFuzzMainEntity(size_t *size);
int int
xmlFuzzResourceLoader(void *data, const char *URL, const char *ID, xmlFuzzResourceLoader(void *data, const char *URL, const char *ID,
int type, int flags, xmlParserInputPtr *out); xmlResourceType type, int flags, xmlParserInputPtr *out);
xmlParserInputPtr xmlParserInputPtr
xmlFuzzEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt); xmlFuzzEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt);

View File

@ -56,7 +56,7 @@ static struct {
static int static int
fuzzResourceRecorder(void *data ATTRIBUTE_UNUSED, const char *URL, fuzzResourceRecorder(void *data ATTRIBUTE_UNUSED, const char *URL,
const char *ID ATTRIBUTE_UNUSED, const char *ID ATTRIBUTE_UNUSED,
int type ATTRIBUTE_UNUSED, int flags, xmlResourceType type ATTRIBUTE_UNUSED, int flags,
xmlParserInputPtr *out) { xmlParserInputPtr *out) {
xmlParserInputPtr in; xmlParserInputPtr in;
static const int chunkSize = 16384; static const int chunkSize = 16384;

View File

@ -36,6 +36,16 @@ extern "C" {
*/ */
#define XML_DEFAULT_VERSION "1.0" #define XML_DEFAULT_VERSION "1.0"
typedef enum {
XML_RESOURCE_UNKNOWN = 0,
XML_RESOURCE_MAIN_DOCUMENT,
XML_RESOURCE_DTD,
XML_RESOURCE_GENERAL_ENTITY,
XML_RESOURCE_PARAMETER_ENTITY,
XML_RESOURCE_XINCLUDE,
XML_RESOURCE_XINCLUDE_TEXT
} xmlResourceType;
/** /**
* xmlParserInput: * xmlParserInput:
* *
@ -161,7 +171,7 @@ typedef struct _xmlAttrHashBucket xmlAttrHashBucket;
typedef int typedef int
(*xmlResourceLoader)(void *ctxt, const char *url, const char *publicId, (*xmlResourceLoader)(void *ctxt, const char *url, const char *publicId,
int type, int flags, xmlParserInputPtr *out); xmlResourceType type, int flags, xmlParserInputPtr *out);
/** /**
* xmlParserCtxt: * xmlParserCtxt:

View File

@ -88,6 +88,9 @@ xmlParserNsUpdateSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
XML_HIDDEN void * XML_HIDDEN void *
xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix); xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix);
XML_HIDDEN xmlParserInputPtr
xmlLoadResource(xmlParserCtxtPtr ctxt, const char *url, const char *publicId,
xmlResourceType type);
XML_HIDDEN xmlParserInputPtr XML_HIDDEN xmlParserInputPtr
xmlNewInputURL(xmlParserCtxtPtr ctxt, const char *url, const char *publicId, xmlNewInputURL(xmlParserCtxtPtr ctxt, const char *url, const char *publicId,
const char *encoding, int flags); const char *encoding, int flags);

View File

@ -7883,9 +7883,7 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
* @ctxt: an XML parser context * @ctxt: an XML parser context
* @entity: an unloaded system entity * @entity: an unloaded system entity
* *
* Load the original content of the given system entity from the * Load the content of an entity.
* ExternalID/SystemID given. This is to be used for Included in Literal
* http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
* *
* Returns 0 in case of success and -1 in case of failure * Returns 0 in case of success and -1 in case of failure
*/ */
@ -7895,6 +7893,7 @@ xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
xmlParserInputPtr *oldinputTab; xmlParserInputPtr *oldinputTab;
const xmlChar *oldencoding; const xmlChar *oldencoding;
xmlChar *content = NULL; xmlChar *content = NULL;
xmlResourceType rtype;
size_t length, i; size_t length, i;
int oldinputNr, oldinputMax; int oldinputNr, oldinputMax;
int ret = -1; int ret = -1;
@ -7909,8 +7908,13 @@ xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
return(-1); return(-1);
} }
input = xmlLoadExternalEntity((char *) entity->URI, if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)
(char *) entity->ExternalID, ctxt); rtype = XML_RESOURCE_PARAMETER_ENTITY;
else
rtype = XML_RESOURCE_GENERAL_ENTITY;
input = xmlLoadResource(ctxt, (char *) entity->URI,
(char *) entity->ExternalID, rtype);
if (input == NULL) if (input == NULL)
return(-1); return(-1);
@ -12171,7 +12175,8 @@ xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctxt, const xmlChar *URL,
if (ctxt == NULL) if (ctxt == NULL)
return(XML_ERR_ARGUMENT); return(XML_ERR_ARGUMENT);
input = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt); input = xmlLoadResource(ctxt, (char *) URL, (char *) ID,
XML_RESOURCE_GENERAL_ENTITY);
if (input == NULL) if (input == NULL)
return(ctxt->errNo); return(ctxt->errNo);
@ -12637,7 +12642,8 @@ xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
URL = uri; URL = uri;
} }
input = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt); input = xmlLoadResource(ctxt, (char *) URL, (char *) ID,
XML_RESOURCE_UNKNOWN);
if (input == NULL) if (input == NULL)
goto error; goto error;
@ -12685,7 +12691,7 @@ xmlCreateURLParserCtxt(const char *filename, int options)
xmlCtxtUseOptions(ctxt, options); xmlCtxtUseOptions(ctxt, options);
ctxt->linenumbers = 1; ctxt->linenumbers = 1;
input = xmlLoadExternalEntity(filename, NULL, ctxt); input = xmlLoadResource(ctxt, filename, NULL, XML_RESOURCE_MAIN_DOCUMENT);
if (input == NULL) { if (input == NULL) {
xmlFreeParserCtxt(ctxt); xmlFreeParserCtxt(ctxt);
return(NULL); return(NULL);

View File

@ -1575,7 +1575,7 @@ xmlNewInputURL(xmlParserCtxtPtr ctxt, const char *url, const char *publicId,
if ((ctxt == NULL) || (url == NULL)) if ((ctxt == NULL) || (url == NULL))
return(NULL); return(NULL);
input = xmlLoadExternalEntity(url, publicId, ctxt); input = xmlLoadResource(ctxt, url, publicId, XML_RESOURCE_MAIN_DOCUMENT);
if (input == NULL) if (input == NULL)
return(NULL); return(NULL);
@ -1992,8 +1992,15 @@ xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
input = xmlNewInputString(ctxt, NULL, (const char *) ent->content, input = xmlNewInputString(ctxt, NULL, (const char *) ent->content,
NULL, XML_INPUT_BUF_STATIC); NULL, XML_INPUT_BUF_STATIC);
} else if (ent->URI != NULL) { } else if (ent->URI != NULL) {
input = xmlLoadExternalEntity((char *) ent->URI, xmlResourceType rtype;
(char *) ent->ExternalID, ctxt);
if (ent->etype == XML_EXTERNAL_PARAMETER_ENTITY)
rtype = XML_RESOURCE_PARAMETER_ENTITY;
else
rtype = XML_RESOURCE_GENERAL_ENTITY;
input = xmlLoadResource(ctxt, (char *) ent->URI,
(char *) ent->ExternalID, rtype);
} else { } else {
return(NULL); return(NULL);
} }
@ -2381,6 +2388,53 @@ xmlCtxtSetResourceLoader(xmlParserCtxtPtr ctxt, xmlResourceLoader loader,
ctxt->resourceCtxt = vctxt; ctxt->resourceCtxt = vctxt;
} }
/**
* xmlLoadResource:
* @ctxt: parser context
* @url: the URL for the entity to load
* @publicId: the Public ID for the entity to load
* @type: resource type
*
* Returns the xmlParserInputPtr or NULL in case of error.
*/
xmlParserInputPtr
xmlLoadResource(xmlParserCtxtPtr ctxt, const char *url, const char *publicId,
xmlResourceType type) {
char *canonicFilename;
xmlParserInputPtr ret;
if (url == NULL)
return(NULL);
if ((ctxt != NULL) && (ctxt->resourceLoader != NULL)) {
int flags = 0;
int code;
if ((ctxt->options & XML_PARSE_NO_UNZIP) == 0)
flags |= XML_INPUT_UNZIP;
if ((ctxt->options & XML_PARSE_NONET) == 0)
flags |= XML_INPUT_NETWORK;
code = ctxt->resourceLoader(ctxt->resourceCtxt, url, publicId, flags,
type, &ret);
if (code != XML_ERR_OK) {
xmlCtxtErrIO(ctxt, code, url);
return(NULL);
}
return(ret);
}
canonicFilename = (char *) xmlCanonicPath((const xmlChar *) url);
if (canonicFilename == NULL) {
xmlCtxtErrMemory(ctxt);
return(NULL);
}
ret = xmlCurrentExternalEntityLoader(canonicFilename, publicId, ctxt);
xmlFree(canonicFilename);
return(ret);
}
/** /**
* xmlLoadExternalEntity: * xmlLoadExternalEntity:
* @URL: the URL for the entity to load * @URL: the URL for the entity to load
@ -2414,39 +2468,7 @@ xmlCtxtSetResourceLoader(xmlParserCtxtPtr ctxt, xmlResourceLoader loader,
xmlParserInputPtr xmlParserInputPtr
xmlLoadExternalEntity(const char *URL, const char *ID, xmlLoadExternalEntity(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) { xmlParserCtxtPtr ctxt) {
char *canonicFilename; return(xmlLoadResource(ctxt, URL, ID, XML_RESOURCE_UNKNOWN));
xmlParserInputPtr ret;
if (URL == NULL)
return(NULL);
if ((ctxt != NULL) && (ctxt->resourceLoader != NULL)) {
int flags = 0;
int code;
if ((ctxt->options & XML_PARSE_NO_UNZIP) == 0)
flags |= XML_INPUT_UNZIP;
if ((ctxt->options & XML_PARSE_NONET) == 0)
flags |= XML_INPUT_NETWORK;
code = ctxt->resourceLoader(ctxt->resourceCtxt, URL, ID, flags,
0, &ret);
if (code != XML_ERR_OK) {
xmlCtxtErrIO(ctxt, code, URL);
return(NULL);
}
return(ret);
}
canonicFilename = (char *) xmlCanonicPath((const xmlChar *) URL);
if (canonicFilename == NULL) {
xmlCtxtErrMemory(ctxt);
return(NULL);
}
ret = xmlCurrentExternalEntityLoader(canonicFilename, ID, ctxt);
xmlFree(canonicFilename);
return(ret);
} }
/************************************************************************ /************************************************************************

View File

@ -115,7 +115,8 @@ static int addEntity(char *name, char *content) {
static int static int
testResourceLoader(void *vctxt ATTRIBUTE_UNUSED, const char *URL, testResourceLoader(void *vctxt ATTRIBUTE_UNUSED, const char *URL,
const char *ID ATTRIBUTE_UNUSED, int type ATTRIBUTE_UNUSED, const char *ID ATTRIBUTE_UNUSED,
xmlResourceType type ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED, xmlParserInputPtr *out) { int flags ATTRIBUTE_UNUSED, xmlParserInputPtr *out) {
int i; int i;

View File

@ -28,6 +28,7 @@
#include "private/buf.h" #include "private/buf.h"
#include "private/error.h" #include "private/error.h"
#include "private/parser.h"
#include "private/tree.h" #include "private/tree.h"
#include "private/xinclude.h" #include "private/xinclude.h"
@ -342,7 +343,7 @@ xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
xmlCtxtUseOptions(pctxt, ctxt->parseFlags); xmlCtxtUseOptions(pctxt, ctxt->parseFlags);
inputStream = xmlLoadExternalEntity(URL, NULL, pctxt); inputStream = xmlLoadResource(pctxt, URL, NULL, XML_RESOURCE_XINCLUDE);
if (inputStream == NULL) if (inputStream == NULL)
goto error; goto error;
@ -1656,7 +1657,8 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
xmlCtxtSetResourceLoader(pctxt, ctxt->resourceLoader, xmlCtxtSetResourceLoader(pctxt, ctxt->resourceLoader,
ctxt->resourceCtxt); ctxt->resourceCtxt);
inputStream = xmlLoadExternalEntity((const char*)url, NULL, pctxt); inputStream = xmlLoadResource(pctxt, (const char*) url, NULL,
XML_RESOURCE_XINCLUDE_TEXT);
if (inputStream == NULL) { if (inputStream == NULL) {
if (pctxt->errNo == XML_ERR_NO_MEMORY) if (pctxt->errNo == XML_ERR_NO_MEMORY)
xmlXIncludeErrMemory(ctxt); xmlXIncludeErrMemory(ctxt);

View File

@ -228,7 +228,7 @@ static xmlResourceLoader defaultResourceLoader = NULL;
static int static int
xmllintResourceLoader(void *ctxt ATTRIBUTE_UNUSED, const char *URL, xmllintResourceLoader(void *ctxt ATTRIBUTE_UNUSED, const char *URL,
const char *ID, int type, int flags, const char *ID, xmlResourceType type, int flags,
xmlParserInputPtr *out) { xmlParserInputPtr *out) {
int code; int code;
int i; int i;