mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-24 13:33:01 +03:00
Fuzz XInclude engine
This commit is contained in:
@@ -13,9 +13,10 @@ XML_SEED_CORPUS_SRC = \
|
|||||||
$(top_srcdir)/test/errors10/*.xml \
|
$(top_srcdir)/test/errors10/*.xml \
|
||||||
$(top_srcdir)/test/namespaces/* \
|
$(top_srcdir)/test/namespaces/* \
|
||||||
$(top_srcdir)/test/valid/*.xml \
|
$(top_srcdir)/test/valid/*.xml \
|
||||||
$(top_srcdir)/test/xmlid/* \
|
|
||||||
$(top_srcdir)/test/VC/* \
|
$(top_srcdir)/test/VC/* \
|
||||||
$(top_srcdir)/test/VCM/*
|
$(top_srcdir)/test/VCM/* \
|
||||||
|
$(top_srcdir)/test/XInclude/docs/* \
|
||||||
|
$(top_srcdir)/test/xmlid/*
|
||||||
|
|
||||||
testFuzzer_SOURCES = testFuzzer.c fuzz.c
|
testFuzzer_SOURCES = testFuzzer.c fuzz.c
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
#include <libxml/xmlerror.h>
|
#include <libxml/xmlerror.h>
|
||||||
|
#include <libxml/xinclude.h>
|
||||||
#include <libxml/xmlreader.h>
|
#include <libxml/xmlreader.h>
|
||||||
#include "fuzz.h"
|
#include "fuzz.h"
|
||||||
|
|
||||||
@@ -46,6 +47,8 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
|||||||
/* Pull parser */
|
/* Pull parser */
|
||||||
|
|
||||||
doc = xmlReadMemory(docBuffer, docSize, NULL, NULL, opts);
|
doc = xmlReadMemory(docBuffer, docSize, NULL, NULL, opts);
|
||||||
|
if (opts & XML_PARSE_XINCLUDE)
|
||||||
|
xmlXIncludeProcessFlags(doc, opts);
|
||||||
/* Also test the serializer. */
|
/* Also test the serializer. */
|
||||||
xmlDocDumpMemory(doc, &out, &outSize);
|
xmlDocDumpMemory(doc, &out, &outSize);
|
||||||
xmlFree(out);
|
xmlFree(out);
|
||||||
@@ -64,6 +67,8 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
xmlParseChunk(ctxt, NULL, 0, 1);
|
xmlParseChunk(ctxt, NULL, 0, 1);
|
||||||
|
if (opts & XML_PARSE_XINCLUDE)
|
||||||
|
xmlXIncludeProcessFlags(ctxt->myDoc, opts);
|
||||||
xmlFreeDoc(ctxt->myDoc);
|
xmlFreeDoc(ctxt->myDoc);
|
||||||
xmlFreeParserCtxt(ctxt);
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <libxml/xinclude.h>
|
||||||
#include "fuzz.h"
|
#include "fuzz.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv) {
|
main(int argc, char **argv) {
|
||||||
int opts = XML_PARSE_NOENT | XML_PARSE_DTDLOAD;
|
int opts = XML_PARSE_NOENT | XML_PARSE_DTDLOAD;
|
||||||
|
xmlDocPtr doc;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf(stderr, "Usage: xmlSeed [FILE]\n");
|
fprintf(stderr, "Usage: xmlSeed [FILE]\n");
|
||||||
@@ -20,7 +22,9 @@ main(int argc, char **argv) {
|
|||||||
|
|
||||||
xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
|
xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
|
||||||
xmlSetExternalEntityLoader(xmlFuzzEntityRecorder);
|
xmlSetExternalEntityLoader(xmlFuzzEntityRecorder);
|
||||||
xmlFreeDoc(xmlReadFile(argv[1], NULL, opts));
|
doc = xmlReadFile(argv[1], NULL, opts);
|
||||||
|
xmlXIncludeProcessFlags(doc, opts);
|
||||||
|
xmlFreeDoc(doc);
|
||||||
xmlFuzzDataCleanup();
|
xmlFuzzDataCleanup();
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
|||||||
15
xinclude.c
15
xinclude.c
@@ -86,6 +86,8 @@ struct _xmlXIncludeCtxt {
|
|||||||
xmlChar * base; /* the current xml:base */
|
xmlChar * base; /* the current xml:base */
|
||||||
|
|
||||||
void *_private; /* application data */
|
void *_private; /* application data */
|
||||||
|
|
||||||
|
unsigned long incTotal; /* total number of processed inclusions */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -729,7 +731,9 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
|
|||||||
* (bug 132597)
|
* (bug 132597)
|
||||||
*/
|
*/
|
||||||
newctxt->parseFlags = ctxt->parseFlags;
|
newctxt->parseFlags = ctxt->parseFlags;
|
||||||
|
newctxt->incTotal = ctxt->incTotal;
|
||||||
xmlXIncludeDoProcess(newctxt, doc, xmlDocGetRootElement(doc));
|
xmlXIncludeDoProcess(newctxt, doc, xmlDocGetRootElement(doc));
|
||||||
|
ctxt->incTotal = newctxt->incTotal;
|
||||||
for (i = 0;i < ctxt->incNr;i++) {
|
for (i = 0;i < ctxt->incNr;i++) {
|
||||||
newctxt->incTab[i]->count--;
|
newctxt->incTab[i]->count--;
|
||||||
newctxt->incTab[i] = NULL;
|
newctxt->incTab[i] = NULL;
|
||||||
@@ -1992,11 +1996,13 @@ xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) {
|
|||||||
newctxt->_private = ctxt->_private;
|
newctxt->_private = ctxt->_private;
|
||||||
newctxt->base = xmlStrdup(ctxt->base); /* Inherit the base from the existing context */
|
newctxt->base = xmlStrdup(ctxt->base); /* Inherit the base from the existing context */
|
||||||
xmlXIncludeSetFlags(newctxt, ctxt->parseFlags);
|
xmlXIncludeSetFlags(newctxt, ctxt->parseFlags);
|
||||||
|
newctxt->incTotal = ctxt->incTotal;
|
||||||
for (child = fallback->children; child != NULL; child = next) {
|
for (child = fallback->children; child != NULL; child = next) {
|
||||||
next = child->next;
|
next = child->next;
|
||||||
if (xmlXIncludeDoProcess(newctxt, ctxt->doc, child) < 0)
|
if (xmlXIncludeDoProcess(newctxt, ctxt->doc, child) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
ctxt->incTotal = newctxt->incTotal;
|
||||||
if (ctxt->nbErrors > oldNbErrors)
|
if (ctxt->nbErrors > oldNbErrors)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
xmlXIncludeFreeContext(newctxt);
|
xmlXIncludeFreeContext(newctxt);
|
||||||
@@ -2411,6 +2417,15 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) {
|
|||||||
do {
|
do {
|
||||||
/* TODO: need to work on entities -> stack */
|
/* TODO: need to work on entities -> stack */
|
||||||
if (xmlXIncludeTestNode(ctxt, cur) == 1) {
|
if (xmlXIncludeTestNode(ctxt, cur) == 1) {
|
||||||
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||||
|
/*
|
||||||
|
* Avoid superlinear expansion by limiting the total number
|
||||||
|
* of replacements.
|
||||||
|
*/
|
||||||
|
if (ctxt->incTotal >= 20)
|
||||||
|
return(-1);
|
||||||
|
#endif
|
||||||
|
ctxt->incTotal++;
|
||||||
xmlXIncludePreProcessNode(ctxt, cur);
|
xmlXIncludePreProcessNode(ctxt, cur);
|
||||||
} else if ((cur->children != NULL) &&
|
} else if ((cur->children != NULL) &&
|
||||||
(cur->children->type != XML_ENTITY_DECL) &&
|
(cur->children->type != XML_ENTITY_DECL) &&
|
||||||
|
|||||||
Reference in New Issue
Block a user