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

Test fuzz targets with dummy driver

Run fuzz targets with files in seed corpus during test.
This commit is contained in:
Nick Wellnhofer 2020-08-24 03:16:25 +02:00
parent 3fcf319378
commit 0d9da0290c
5 changed files with 149 additions and 24 deletions

View File

@ -21,9 +21,11 @@ XML_SEED_CORPUS_SRC = \
testFuzzer_SOURCES = testFuzzer.c fuzz.c
.PHONY: tests clean-corpus
.PHONY: tests corpus clean-corpus
tests: testFuzzer$(EXEEXT)
corpus: seed/html.stamp seed/schema.stamp seed/xml.stamp seed/xpath.stamp
tests: testFuzzer$(EXEEXT) corpus
@echo "## Running fuzzer tests"
@./testFuzzer$(EXEEXT)

View File

@ -4,8 +4,11 @@
* See Copyright for the status of this software.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <libxml/hash.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
@ -361,3 +364,32 @@ xmlFuzzExtractStrings(const char *data, size_t size, char **strings,
return(ret);
}
char *
xmlSlurpFile(const char *path, size_t *sizeRet) {
FILE *file;
struct stat statbuf;
char *data;
size_t size;
if ((stat(path, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode)))
return(NULL);
size = statbuf.st_size;
file = fopen(path, "rb");
if (file == NULL)
return(NULL);
data = xmlMalloc(size + 1);
if (data != NULL) {
if (fread(data, 1, size, file) != size) {
xmlFree(data);
data = NULL;
} else {
data[size] = 0;
if (sizeRet != NULL)
*sizeRet = size;
}
}
fclose(file);
return(data);
}

View File

@ -8,6 +8,7 @@
#define __XML_FUZZERCOMMON_H__
#include <stddef.h>
#include <stdio.h>
#include <libxml/parser.h>
#ifdef __cplusplus
@ -61,6 +62,9 @@ size_t
xmlFuzzExtractStrings(const char *data, size_t size, char **strings,
size_t numStrings);
char *
xmlSlurpFile(const char *path, size_t *size);
#ifdef __cplusplus
}
#endif

View File

@ -6,13 +6,93 @@
*/
#include <string.h>
#include <glob.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlstring.h>
#include "fuzz.h"
int
main() {
#define LLVMFuzzerInitialize fuzzHtmlInit
#define LLVMFuzzerTestOneInput fuzzHtml
#include "html.c"
#undef LLVMFuzzerInitialize
#undef LLVMFuzzerTestOneInput
#define LLVMFuzzerInitialize fuzzRegexpInit
#define LLVMFuzzerTestOneInput fuzzRegexp
#include "regexp.c"
#undef LLVMFuzzerInitialize
#undef LLVMFuzzerTestOneInput
#define LLVMFuzzerInitialize fuzzSchemaInit
#define LLVMFuzzerTestOneInput fuzzSchema
#include "schema.c"
#undef LLVMFuzzerInitialize
#undef LLVMFuzzerTestOneInput
#define LLVMFuzzerInitialize fuzzUriInit
#define LLVMFuzzerTestOneInput fuzzUri
#include "uri.c"
#undef LLVMFuzzerInitialize
#undef LLVMFuzzerTestOneInput
#define LLVMFuzzerInitialize fuzzXmlInit
#define LLVMFuzzerTestOneInput fuzzXml
#include "xml.c"
#undef LLVMFuzzerInitialize
#undef LLVMFuzzerTestOneInput
#define LLVMFuzzerInitialize fuzzXPathInit
#define LLVMFuzzerTestOneInput fuzzXPath
#include "xpath.c"
#undef LLVMFuzzerInitialize
#undef LLVMFuzzerTestOneInput
typedef int
(*initFunc)(int *argc, char ***argv);
typedef int
(*fuzzFunc)(const char *data, size_t size);
int numInputs;
static int
testFuzzer(initFunc init, fuzzFunc fuzz, const char *pattern) {
glob_t globbuf;
int ret = -1;
int i;
if (glob(pattern, 0, NULL, &globbuf) != 0) {
fprintf(stderr, "pattern %s matches no files\n", pattern);
return(-1);
}
if (init != NULL)
init(NULL, NULL);
for (i = 0; i < globbuf.gl_pathc; i++) {
const char *path = globbuf.gl_pathv[i];
char *data;
size_t size;
data = xmlSlurpFile(path, &size);
if (data == NULL) {
fprintf(stderr, "couldn't read %s\n", path);
goto error;
}
fuzz(data, size);
xmlFree(data);
numInputs++;
}
ret = 0;
error:
globfree(&globbuf);
return(ret);
}
static int
testEntityLoader() {
static const char data[] =
"doc.xml\\\n"
"<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
@ -53,3 +133,28 @@ main() {
return(ret);
}
int
main() {
int ret = 0;
if (testEntityLoader() != 0)
ret = 1;
if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0)
ret = 1;
if (testFuzzer(fuzzRegexpInit, fuzzRegexp, "seed/regexp/*") != 0)
ret = 1;
if (testFuzzer(fuzzSchemaInit, fuzzSchema, "seed/schema/*") != 0)
ret = 1;
if (testFuzzer(NULL, fuzzUri, "seed/uri/*") != 0)
ret = 1;
if (testFuzzer(fuzzXmlInit, fuzzXml, "seed/xml/*") != 0)
ret = 1;
if (testFuzzer(fuzzXPathInit, fuzzXPath, "seed/xpath/*") != 0)
ret = 1;
if (ret == 0)
printf("Successfully tested %d inputs\n", numInputs);
return(ret);
}

View File

@ -52,27 +52,12 @@ main(int argc, char **argv) {
for (i = 0; i < globbuf.gl_pathc; i++) {
char *path = globbuf.gl_pathv[i];
FILE *xmlFile;
struct stat statbuf;
if ((stat(path, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode)))
continue;
size = statbuf.st_size;
xmlFile = fopen(path, "rb");
if (xmlFile == NULL) {
ret = 1;
continue;
}
xml.data = xmlMalloc(size + 1);
xml.data = xmlSlurpFile(path, NULL);
if (xml.data == NULL) {
ret = 1;
goto close;
continue;
}
if (fread(xml.data, 1, size, xmlFile) != size) {
ret = 1;
goto free;
}
xml.data[size] = 0;
xml.name = basename(path);
xml.prefix = xml.name;
xml.counter = 1;
@ -82,10 +67,7 @@ main(int argc, char **argv) {
if (processXml(argv[1], &xml, "xptr", 1) != 0)
ret = 1;
free:
xmlFree(xml.data);
close:
fclose(xmlFile);
}
globfree(&globbuf);