1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-10-26 12:25:09 +03:00

Move entity recorder to fuzz.c

This commit is contained in:
Nick Wellnhofer 2020-06-21 12:14:19 +02:00
parent 681f094e5b
commit ffd31dbefd
3 changed files with 65 additions and 72 deletions

View File

@ -121,6 +121,23 @@ xmlFuzzReadRemaining(size_t *size) {
return(ret);
}
/*
* Write a random-length string to stdout in a format similar to
* FuzzedDataProvider. Backslash followed by newline marks the end of the
* string. Two backslashes are used to escape a backslash.
*/
static void
xmlFuzzWriteString(const char *str) {
for (; *str; str++) {
int c = (unsigned char) *str;
putchar(c);
if (c == '\\')
putchar(c);
}
putchar('\\');
putchar('\n');
}
/**
* xmlFuzzReadString:
* @size: size of string in bytes
@ -169,6 +186,47 @@ xmlFuzzReadString(size_t *size) {
return(NULL);
}
/*
* A custom entity loader that writes all external DTDs or entities to a
* single file in the format expected by xmlFuzzEntityLoader.
*/
xmlParserInputPtr
xmlFuzzEntityRecorder(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlParserInputPtr in;
static const int chunkSize = 16384;
int len;
in = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
if (in == NULL)
return(NULL);
if (fuzzData.entities == NULL) {
fuzzData.entities = xmlHashCreate(4);
} else if (xmlHashLookup(fuzzData.entities,
(const xmlChar *) URL) != NULL) {
return(in);
}
do {
len = xmlParserInputBufferGrow(in->buf, chunkSize);
if (len < 0) {
fprintf(stderr, "Error reading %s\n", URL);
xmlFreeInputStream(in);
return(NULL);
}
} while (len > 0);
xmlFuzzWriteString(URL);
xmlFuzzWriteString((char *) xmlBufContent(in->buf->buffer));
xmlFreeInputStream(in);
xmlHashAddEntry(fuzzData.entities, (const xmlChar *) URL, NULL);
return(xmlNoNetExternalEntityLoader(URL, ID, ctxt));
}
/**
* xmlFuzzReadEntities:
*

View File

@ -36,6 +36,9 @@ xmlFuzzReadInt(void);
const char *
xmlFuzzReadRemaining(size_t *size);
xmlParserInputPtr
xmlFuzzEntityRecorder(const char *URL, const char *ID, xmlParserCtxtPtr ctxt);
void
xmlFuzzReadEntities(void);
@ -43,8 +46,7 @@ const char *
xmlFuzzMainEntity(size_t *size);
xmlParserInputPtr
xmlFuzzEntityLoader(const char *URL, const char *ID ATTRIBUTE_UNUSED,
xmlParserCtxtPtr ctxt);
xmlFuzzEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt);
size_t
xmlFuzzExtractStrings(const char *data, size_t size, char **strings,

View File

@ -5,74 +5,8 @@
*/
#include <stdio.h>
#include <string.h>
#include <libxml/hash.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/xmlIO.h>
#include <libxml/xmlerror.h>
#include "fuzz.h"
static xmlHashTablePtr entities;
static void
errorFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED, ...) {
/* Discard error messages. */
}
/*
* Write a random-length string in a format similar to FuzzedDataProvider.
* Backslash followed by newline marks the end of the string. Two
* backslashes are used to escape a backslash.
*/
static void
writeEscaped(const char *str) {
for (; *str; str++) {
int c = (unsigned char) *str;
putchar(c);
if (c == '\\')
putchar(c);
}
putchar('\\');
putchar('\n');
}
/*
* A custom entity loader that writes all external DTDs or entities to a
* single file in the format expected by xmlFuzzEntityLoader.
*/
static xmlParserInputPtr
entityLoader(const char *URL, const char *ID, xmlParserCtxtPtr context) {
xmlParserInputPtr in;
static const int chunkSize = 16384;
int len;
in = xmlNoNetExternalEntityLoader(URL, ID, context);
if (in == NULL)
return(NULL);
if (xmlHashLookup(entities, (const xmlChar *) URL) != NULL)
return(in);
do {
len = xmlParserInputBufferGrow(in->buf, chunkSize);
if (len < 0) {
fprintf(stderr, "Error reading %s\n", URL);
xmlFreeInputStream(in);
return(NULL);
}
} while (len > 0);
writeEscaped(URL);
writeEscaped((char *) xmlBufContent(in->buf->buffer));
xmlFreeInputStream(in);
xmlHashAddEntry(entities, (const xmlChar *) URL, "seen");
return(xmlNoNetExternalEntityLoader(URL, ID, context));
}
int
main(int argc, char **argv) {
int opts = XML_PARSE_NOENT | XML_PARSE_DTDLOAD;
@ -83,11 +17,10 @@ main(int argc, char **argv) {
fwrite(&opts, sizeof(opts), 1, stdout);
entities = xmlHashCreate(4);
xmlSetGenericErrorFunc(NULL, errorFunc);
xmlSetExternalEntityLoader(entityLoader);
xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
xmlSetExternalEntityLoader(xmlFuzzEntityRecorder);
xmlFreeDoc(xmlReadFile(argv[1], NULL, opts));
xmlHashFree(entities, NULL);
xmlFuzzDataCleanup();
return(0);
}