1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-31 21:50:33 +03:00

xmllint: Switch to resource loader

This commit is contained in:
Nick Wellnhofer
2024-06-11 18:14:43 +02:00
parent ab5e6debd1
commit f96dca9c0e
2 changed files with 55 additions and 73 deletions

View File

@@ -198,12 +198,11 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
pushArg(NULL); pushArg(NULL);
xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc); xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
#ifdef LIBXML_CATALOG_ENABLED #ifdef LIBXML_CATALOG_ENABLED
xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE); xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE);
#endif #endif
xmllintMain(vars.argi - 1, vars.argv); xmllintMain(vars.argi - 1, vars.argv, xmlFuzzResourceLoader);
xmlMemSetup(free, malloc, realloc, xmlMemStrdup); xmlMemSetup(free, malloc, realloc, xmlMemStrdup);

119
xmllint.c
View File

@@ -224,15 +224,13 @@ void parsePath(const xmlChar *path) {
} }
} }
static xmlExternalEntityLoader defaultEntityLoader = NULL; static xmlResourceLoader defaultResourceLoader = NULL;
static xmlParserInputPtr
xmllintExternalEntityLoader(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlParserInputPtr ret;
warningSAXFunc warning = NULL;
errorSAXFunc err = NULL;
static int
xmllintResourceLoader(void *ctxt ATTRIBUTE_UNUSED, const char *URL,
const char *ID, int type, int flags,
xmlParserInputPtr *out) {
int code;
int i; int i;
const char *lastsegment = URL; const char *lastsegment = URL;
const char *iter = URL; const char *iter = URL;
@@ -245,66 +243,43 @@ xmllintExternalEntityLoader(const char *URL, const char *ID,
} }
} }
if ((ctxt != NULL) && (ctxt->sax != NULL)) { if (defaultResourceLoader != NULL)
warning = ctxt->sax->warning; code = defaultResourceLoader(NULL, URL, ID, type, flags, out);
err = ctxt->sax->error; else
ctxt->sax->warning = NULL; code = xmlInputCreateUrl(URL, flags, out);
ctxt->sax->error = NULL; if (code != XML_IO_ENOENT) {
if ((load_trace) && (code == XML_ERR_OK)) {
fprintf(ERR_STREAM, "Loaded URL=\"%s\" ID=\"%s\"\n",
URL, ID ? ID : "(null)");
}
return(code);
} }
if (defaultEntityLoader != NULL) { for (i = 0; i < nbpaths; i++) {
ret = defaultEntityLoader(URL, ID, ctxt);
if (ret != NULL) {
if (warning != NULL)
ctxt->sax->warning = warning;
if (err != NULL)
ctxt->sax->error = err;
if (load_trace) {
fprintf \
(ERR_STREAM,
"Loaded URL=\"%s\" ID=\"%s\"\n",
URL ? URL : "(null)",
ID ? ID : "(null)");
}
return(ret);
}
}
for (i = 0;i < nbpaths;i++) {
xmlChar *newURL; xmlChar *newURL;
newURL = xmlStrdup((const xmlChar *) paths[i]); newURL = xmlStrdup((const xmlChar *) paths[i]);
newURL = xmlStrcat(newURL, (const xmlChar *) "/"); newURL = xmlStrcat(newURL, (const xmlChar *) "/");
newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment); newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
if (newURL != NULL) { if (newURL != NULL) {
ret = defaultEntityLoader((const char *)newURL, ID, ctxt); if (defaultResourceLoader != NULL)
if (ret != NULL) { code = defaultResourceLoader(NULL, (const char *) newURL, ID,
if (warning != NULL) type, flags, out);
ctxt->sax->warning = warning; else
if (err != NULL) code = xmlInputCreateUrl((const char *) newURL, flags, out);
ctxt->sax->error = err; if (code != XML_IO_ENOENT) {
if (load_trace) { if ((load_trace) && (code == XML_ERR_OK)) {
fprintf \ fprintf(ERR_STREAM, "Loaded URL=\"%s\" ID=\"%s\"\n",
(ERR_STREAM, newURL, ID ? ID : "(null)");
"Loaded URL=\"%s\" ID=\"%s\"\n",
newURL,
ID ? ID : "(null)");
} }
xmlFree(newURL); xmlFree(newURL);
return(ret); return(code);
} }
xmlFree(newURL); xmlFree(newURL);
} }
} }
if (err != NULL)
ctxt->sax->error = err; return(XML_IO_ENOENT);
if (warning != NULL) {
ctxt->sax->warning = warning;
if (URL != NULL)
warning(ctxt, "failed to load external entity \"%s\"\n", URL);
else if (ID != NULL)
warning(ctxt, "failed to load external entity \"%s\"\n", ID);
}
return(NULL);
} }
/************************************************************************ /************************************************************************
@@ -1644,6 +1619,8 @@ testSAX(const char *filename) {
progresult = XMLLINT_ERR_MEM; progresult = XMLLINT_ERR_MEM;
return; return;
} }
xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
if (maxAmpl > 0) if (maxAmpl > 0)
xmlCtxtSetMaxAmplification(ctxt, maxAmpl); xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
@@ -1803,8 +1780,10 @@ static void streamFile(const char *filename) {
if (reader != NULL) { if (reader != NULL) {
xmlTextReaderSetResourceLoader(reader, xmllintResourceLoader, NULL);
if (maxAmpl > 0) if (maxAmpl > 0)
xmlTextReaderSetMaxAmplification(reader, maxAmpl); xmlTextReaderSetMaxAmplification(reader, maxAmpl);
#ifdef LIBXML_SCHEMAS_ENABLED #ifdef LIBXML_SCHEMAS_ENABLED
if (relaxng != NULL) { if (relaxng != NULL) {
if ((timing) && (!repeat)) { if ((timing) && (!repeat)) {
@@ -2213,10 +2192,15 @@ parseFile(const char *filename, xmlParserCtxtPtr rectxt) {
#endif #endif
if (html) { if (html) {
ctxt = htmlNewParserCtxt();
xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
if (strcmp(filename, "-") == 0) if (strcmp(filename, "-") == 0)
doc = htmlReadFd(STDIN_FILENO, "-", NULL, options); doc = htmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL, options);
else else
doc = htmlReadFile(filename, NULL, options); doc = htmlCtxtReadFile(ctxt, filename, NULL, options);
htmlFreeParserCtxt(ctxt);
return(doc); return(doc);
} }
@@ -2248,8 +2232,9 @@ parseFile(const char *filename, xmlParserCtxtPtr rectxt) {
fclose(f); fclose(f);
return(NULL); return(NULL);
} }
xmlCtxtUseOptions(ctxt, options);
xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
xmlCtxtUseOptions(ctxt, options);
if (maxAmpl > 0) if (maxAmpl > 0)
xmlCtxtSetMaxAmplification(ctxt, maxAmpl); xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
@@ -2281,6 +2266,7 @@ parseFile(const char *filename, xmlParserCtxtPtr rectxt) {
ctxt = rectxt; ctxt = rectxt;
} }
xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
if (maxAmpl > 0) if (maxAmpl > 0)
xmlCtxtSetMaxAmplification(ctxt, maxAmpl); xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
@@ -3109,7 +3095,7 @@ skipArgs(const char *arg) {
} }
static int static int
xmllintMain(int argc, const char **argv) { xmllintMain(int argc, const char **argv, xmlResourceLoader loader) {
int i, acount; int i, acount;
int files = 0; int files = 0;
int version = 0; int version = 0;
@@ -3123,6 +3109,8 @@ xmllintMain(int argc, const char **argv) {
int nocatalogs = 0; int nocatalogs = 0;
#endif #endif
defaultResourceLoader = loader;
#ifdef XMLLINT_FUZZ #ifdef XMLLINT_FUZZ
#ifdef LIBXML_DEBUG_ENABLED #ifdef LIBXML_DEBUG_ENABLED
shell = 0; shell = 0;
@@ -3196,7 +3184,6 @@ xmllintMain(int argc, const char **argv) {
#endif #endif
options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES; options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
maxAmpl = 0; maxAmpl = 0;
defaultEntityLoader = NULL;
#endif /* XMLLINT_FUZZ */ #endif /* XMLLINT_FUZZ */
if (argc <= 1) { if (argc <= 1) {
@@ -3512,9 +3499,6 @@ xmllintMain(int argc, const char **argv) {
else if ((!strcmp(argv[i], "-nonet")) || else if ((!strcmp(argv[i], "-nonet")) ||
(!strcmp(argv[i], "--nonet"))) { (!strcmp(argv[i], "--nonet"))) {
options |= XML_PARSE_NONET; options |= XML_PARSE_NONET;
#ifndef XMLLINT_FUZZ
xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
#endif
} else if ((!strcmp(argv[i], "-nocompact")) || } else if ((!strcmp(argv[i], "-nocompact")) ||
(!strcmp(argv[i], "--nocompact"))) { (!strcmp(argv[i], "--nocompact"))) {
options &= ~XML_PARSE_COMPACT; options &= ~XML_PARSE_COMPACT;
@@ -3576,9 +3560,6 @@ xmllintMain(int argc, const char **argv) {
} }
#endif #endif
defaultEntityLoader = xmlGetExternalEntityLoader();
xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
if ((htmlout) && (!nowrap)) { if ((htmlout) && (!nowrap)) {
fprintf(ERR_STREAM, fprintf(ERR_STREAM,
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n"); "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
@@ -3641,6 +3622,7 @@ xmllintMain(int argc, const char **argv) {
progresult = XMLLINT_ERR_MEM; progresult = XMLLINT_ERR_MEM;
goto error; goto error;
} }
xmlRelaxNGSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
relaxngschemas = xmlRelaxNGParse(ctxt); relaxngschemas = xmlRelaxNGParse(ctxt);
if (relaxngschemas == NULL) { if (relaxngschemas == NULL) {
fprintf(ERR_STREAM, fprintf(ERR_STREAM,
@@ -3667,6 +3649,7 @@ xmllintMain(int argc, const char **argv) {
progresult = XMLLINT_ERR_MEM; progresult = XMLLINT_ERR_MEM;
goto error; goto error;
} }
xmlSchemaSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
wxschemas = xmlSchemaParse(ctxt); wxschemas = xmlSchemaParse(ctxt);
if (wxschemas == NULL) { if (wxschemas == NULL) {
fprintf(ERR_STREAM, fprintf(ERR_STREAM,
@@ -3706,6 +3689,8 @@ xmllintMain(int argc, const char **argv) {
progresult = XMLLINT_ERR_MEM; progresult = XMLLINT_ERR_MEM;
goto error; goto error;
} }
xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
if (maxAmpl > 0) if (maxAmpl > 0)
xmlCtxtSetMaxAmplification(ctxt, maxAmpl); xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
@@ -3771,8 +3756,6 @@ xmllintMain(int argc, const char **argv) {
goto error; goto error;
error: error:
if (defaultEntityLoader != NULL)
xmlSetExternalEntityLoader(defaultEntityLoader);
xmlCleanupParser(); xmlCleanupParser();
return(progresult); return(progresult);
@@ -3781,7 +3764,7 @@ error:
#ifndef XMLLINT_FUZZ #ifndef XMLLINT_FUZZ
int int
main(int argc, char **argv) { main(int argc, char **argv) {
return(xmllintMain(argc, (const char **) argv)); return(xmllintMain(argc, (const char **) argv, NULL));
} }
#endif #endif