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:
parent
681f094e5b
commit
ffd31dbefd
58
fuzz/fuzz.c
58
fuzz/fuzz.c
@ -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:
|
||||
*
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user