summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2023-02-26 16:54:07 +0100
committerNick Wellnhofer <wellnhofer@aevum.de>2023-03-09 19:05:53 +0100
commit93407f6d3234ae3f036154d69f07da291eff34ff (patch)
tree95630b392b697442468de47b0b0d2997190657ac
parentb816b45b7e0b6b7cad46f1cb0365ef8084a815a1 (diff)
downloadlibxslt-93407f6d3234ae3f036154d69f07da291eff34ff.tar.gz
fuzz: Improve fuzzers
- Fuzz with multiple inputs. - Generate XSLT seed corpus from tests. - Inject malloc failures. Fixes #84.
-rw-r--r--configure.ac2
-rw-r--r--tests/fuzz/.gitignore2
-rw-r--r--tests/fuzz/Makefile.am41
-rw-r--r--tests/fuzz/fuzz.c690
-rw-r--r--tests/fuzz/fuzz.h61
-rw-r--r--tests/fuzz/genSeed.c487
-rw-r--r--tests/fuzz/seed/xpath/crypto_md41
-rw-r--r--tests/fuzz/seed/xpath/crypto_md51
-rw-r--r--tests/fuzz/seed/xpath/crypto_rc4_decrypt1
-rw-r--r--tests/fuzz/seed/xpath/crypto_sha11
-rw-r--r--tests/fuzz/seed/xpath/date_add1
-rw-r--r--tests/fuzz/seed/xpath/date_add_duration1
-rw-r--r--tests/fuzz/seed/xpath/date_date1
-rw-r--r--tests/fuzz/seed/xpath/date_date_time1
-rw-r--r--tests/fuzz/seed/xpath/date_day_abbreviation1
-rw-r--r--tests/fuzz/seed/xpath/date_day_in_month1
-rw-r--r--tests/fuzz/seed/xpath/date_day_in_week1
-rw-r--r--tests/fuzz/seed/xpath/date_day_in_year1
-rw-r--r--tests/fuzz/seed/xpath/date_day_name1
-rw-r--r--tests/fuzz/seed/xpath/date_day_of_week_in_month1
-rw-r--r--tests/fuzz/seed/xpath/date_difference1
-rw-r--r--tests/fuzz/seed/xpath/date_duration1
-rw-r--r--tests/fuzz/seed/xpath/date_format_date1
-rw-r--r--tests/fuzz/seed/xpath/date_hour_in_day1
-rw-r--r--tests/fuzz/seed/xpath/date_leap_year1
-rw-r--r--tests/fuzz/seed/xpath/date_minute_in_hour1
-rw-r--r--tests/fuzz/seed/xpath/date_month_abbreviation1
-rw-r--r--tests/fuzz/seed/xpath/date_month_in_year1
-rw-r--r--tests/fuzz/seed/xpath/date_month_name1
-rw-r--r--tests/fuzz/seed/xpath/date_parse_date1
-rw-r--r--tests/fuzz/seed/xpath/date_second_in_minute1
-rw-r--r--tests/fuzz/seed/xpath/date_seconds1
-rw-r--r--tests/fuzz/seed/xpath/date_sum1
-rw-r--r--tests/fuzz/seed/xpath/date_time1
-rw-r--r--tests/fuzz/seed/xpath/date_week_in_month1
-rw-r--r--tests/fuzz/seed/xpath/date_week_in_year1
-rw-r--r--tests/fuzz/seed/xpath/date_year1
-rw-r--r--tests/fuzz/seed/xpath/dyn_evaluate1
-rw-r--r--tests/fuzz/seed/xpath/dyn_map1
-rw-r--r--tests/fuzz/seed/xpath/expr_arith1
-rw-r--r--tests/fuzz/seed/xpath/expr_location_path1
-rw-r--r--tests/fuzz/seed/xpath/expr_predicate1
-rw-r--r--tests/fuzz/seed/xpath/exsl_node_set_11
-rw-r--r--tests/fuzz/seed/xpath/exsl_node_set_21
-rw-r--r--tests/fuzz/seed/xpath/exsl_object_type1
-rw-r--r--tests/fuzz/seed/xpath/func_boolean1
-rw-r--r--tests/fuzz/seed/xpath/func_ceiling1
-rw-r--r--tests/fuzz/seed/xpath/func_concat1
-rw-r--r--tests/fuzz/seed/xpath/func_contains1
-rw-r--r--tests/fuzz/seed/xpath/func_count1
-rw-r--r--tests/fuzz/seed/xpath/func_false1
-rw-r--r--tests/fuzz/seed/xpath/func_floor1
-rw-r--r--tests/fuzz/seed/xpath/func_id1
-rw-r--r--tests/fuzz/seed/xpath/func_lang1
-rw-r--r--tests/fuzz/seed/xpath/func_last1
-rw-r--r--tests/fuzz/seed/xpath/func_local_name1
-rw-r--r--tests/fuzz/seed/xpath/func_name1
-rw-r--r--tests/fuzz/seed/xpath/func_namespace_uri1
-rw-r--r--tests/fuzz/seed/xpath/func_normalize_space1
-rw-r--r--tests/fuzz/seed/xpath/func_not1
-rw-r--r--tests/fuzz/seed/xpath/func_number_node1
-rw-r--r--tests/fuzz/seed/xpath/func_number_str1
-rw-r--r--tests/fuzz/seed/xpath/func_position1
-rw-r--r--tests/fuzz/seed/xpath/func_round1
-rw-r--r--tests/fuzz/seed/xpath/func_starts_with1
-rw-r--r--tests/fuzz/seed/xpath/func_string_length1
-rw-r--r--tests/fuzz/seed/xpath/func_string_node1
-rw-r--r--tests/fuzz/seed/xpath/func_string_num1
-rw-r--r--tests/fuzz/seed/xpath/func_substring1
-rw-r--r--tests/fuzz/seed/xpath/func_substring_after1
-rw-r--r--tests/fuzz/seed/xpath/func_substring_before1
-rw-r--r--tests/fuzz/seed/xpath/func_sum1
-rw-r--r--tests/fuzz/seed/xpath/func_translate1
-rw-r--r--tests/fuzz/seed/xpath/func_true1
-rw-r--r--tests/fuzz/seed/xpath/math_abs1
-rw-r--r--tests/fuzz/seed/xpath/math_acos1
-rw-r--r--tests/fuzz/seed/xpath/math_asin1
-rw-r--r--tests/fuzz/seed/xpath/math_atan1
-rw-r--r--tests/fuzz/seed/xpath/math_atan21
-rw-r--r--tests/fuzz/seed/xpath/math_constant1
-rw-r--r--tests/fuzz/seed/xpath/math_cos1
-rw-r--r--tests/fuzz/seed/xpath/math_exp1
-rw-r--r--tests/fuzz/seed/xpath/math_highest1
-rw-r--r--tests/fuzz/seed/xpath/math_log1
-rw-r--r--tests/fuzz/seed/xpath/math_lowest1
-rw-r--r--tests/fuzz/seed/xpath/math_max1
-rw-r--r--tests/fuzz/seed/xpath/math_min1
-rw-r--r--tests/fuzz/seed/xpath/math_power1
-rw-r--r--tests/fuzz/seed/xpath/math_random1
-rw-r--r--tests/fuzz/seed/xpath/math_sin1
-rw-r--r--tests/fuzz/seed/xpath/math_sqrt1
-rw-r--r--tests/fuzz/seed/xpath/math_tan1
-rw-r--r--tests/fuzz/seed/xpath/saxon_eval1
-rw-r--r--tests/fuzz/seed/xpath/saxon_evaluate1
-rw-r--r--tests/fuzz/seed/xpath/saxon_line_number_01
-rw-r--r--tests/fuzz/seed/xpath/saxon_line_number_11
-rw-r--r--tests/fuzz/seed/xpath/saxon_systemId1
-rw-r--r--tests/fuzz/seed/xpath/set_difference1
-rw-r--r--tests/fuzz/seed/xpath/set_distinct1
-rw-r--r--tests/fuzz/seed/xpath/set_has_same_node1
-rw-r--r--tests/fuzz/seed/xpath/set_intersection1
-rw-r--r--tests/fuzz/seed/xpath/set_leading1
-rw-r--r--tests/fuzz/seed/xpath/set_trailing1
-rw-r--r--tests/fuzz/seed/xpath/str_align_center1
-rw-r--r--tests/fuzz/seed/xpath/str_align_left1
-rw-r--r--tests/fuzz/seed/xpath/str_align_right1
-rw-r--r--tests/fuzz/seed/xpath/str_concat1
-rw-r--r--tests/fuzz/seed/xpath/str_decode_uri1
-rw-r--r--tests/fuzz/seed/xpath/str_encode_uri_11
-rw-r--r--tests/fuzz/seed/xpath/str_encode_uri_21
-rw-r--r--tests/fuzz/seed/xpath/str_padding1
-rw-r--r--tests/fuzz/seed/xpath/str_replace1
-rw-r--r--tests/fuzz/seed/xpath/str_split1
-rw-r--r--tests/fuzz/seed/xpath/str_tokenize1
-rw-r--r--tests/fuzz/seed/xpath/xslt_current1
-rw-r--r--tests/fuzz/seed/xpath/xslt_document1
-rw-r--r--tests/fuzz/seed/xpath/xslt_element_available1
-rw-r--r--tests/fuzz/seed/xpath/xslt_format_number1
-rw-r--r--tests/fuzz/seed/xpath/xslt_format_number_neg1
-rw-r--r--tests/fuzz/seed/xpath/xslt_function_available1
-rw-r--r--tests/fuzz/seed/xpath/xslt_generate_id1
-rw-r--r--tests/fuzz/seed/xpath/xslt_system_property1
-rw-r--r--tests/fuzz/seed/xpath/xslt_unparsed_entity_uri1
-rw-r--r--tests/fuzz/seed/xslt/attr_set9
-rw-r--r--tests/fuzz/seed/xslt/cdata4
-rw-r--r--tests/fuzz/seed/xslt/decimal_format15
-rw-r--r--tests/fuzz/seed/xslt/element5
-rw-r--r--tests/fuzz/seed/xslt/extension7
-rw-r--r--tests/fuzz/seed/xslt/html4
-rw-r--r--tests/fuzz/seed/xslt/key4
-rw-r--r--tests/fuzz/seed/xslt/lre3
-rw-r--r--tests/fuzz/seed/xslt/mode4
-rw-r--r--tests/fuzz/seed/xslt/number10
-rw-r--r--tests/fuzz/seed/xslt/output4
-rw-r--r--tests/fuzz/seed/xslt/param8
-rw-r--r--tests/fuzz/seed/xslt/sort6
-rw-r--r--tests/fuzz/seed/xslt/strip_space6
-rw-r--r--tests/fuzz/seed/xslt/text4
-rw-r--r--tests/fuzz/seed/xslt/variable4
-rw-r--r--tests/fuzz/seed/xslt/xhtml4
-rw-r--r--tests/fuzz/testTargets.c38
-rw-r--r--tests/fuzz/xpath.c5
-rw-r--r--tests/fuzz/xpath.dict15
-rw-r--r--tests/fuzz/xpath.xml19
-rw-r--r--tests/fuzz/xslt.c5
-rw-r--r--tests/fuzz/xslt.dict15
-rw-r--r--tests/fuzz/xslt.xml21
147 files changed, 1162 insertions, 457 deletions
diff --git a/configure.ac b/configure.ac
index 8064c7bc..540a2f20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -564,7 +564,5 @@ doc/EXSLT/devhelp/Makefile
xslt-config
libxslt.spec
])
-AC_CONFIG_LINKS([tests/fuzz/xpath.xml:tests/fuzz/xpath.xml])
-AC_CONFIG_LINKS([tests/fuzz/xslt.xml:tests/fuzz/xslt.xml])
AC_OUTPUT
diff --git a/tests/fuzz/.gitignore b/tests/fuzz/.gitignore
index 7515dea5..c2f774ff 100644
--- a/tests/fuzz/.gitignore
+++ b/tests/fuzz/.gitignore
@@ -1,4 +1,6 @@
/corpus/
+/genSeed
+/seed/
/testTargets
/xpath
/xslt
diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am
index 006e6215..56accdb2 100644
--- a/tests/fuzz/Makefile.am
+++ b/tests/fuzz/Makefile.am
@@ -1,21 +1,15 @@
LIBXSLT_LIBS = $(top_builddir)/libxslt/libxslt.la \
$(top_builddir)/libexslt/libexslt.la
-EXTRA_PROGRAMS = xpath xslt
+EXTRA_PROGRAMS = genSeed xpath xslt
check_PROGRAMS = testTargets
-EXTRA_DIST = xpath.dict xpath.xml xslt.dict xslt.xml seed
+EXTRA_DIST = xpath.dict xpath.xml xslt.dict seed
CLEANFILES = $(EXTRA_PROGRAMS)
AM_CPPFLAGS = -I$(top_srcdir)
DEPENDENCIES = $(LIBXSLT_LIBS)
LDADD = $(LIBXSLT_LIBS) \
$(LIBXML_LIBS) $(EXTRA_LIBS) $(LIBM)
-xpath_SOURCES = xpath.c fuzz.c fuzz.h
-xpath_LDFLAGS = -fsanitize=fuzzer
-
-xslt_SOURCES = xslt.c fuzz.c fuzz.h
-xslt_LDFLAGS = -fsanitize=fuzzer
-
testTargets_SOURCES = testTargets.c fuzz.c fuzz.h
$(top_builddir)/libxslt/libxslt.la:
@@ -28,16 +22,39 @@ $(top_builddir)/libexslt/libexslt.la: $(top_builddir)/libxslt/libxslt.la
check-local: $(check_PROGRAMS)
@echo '## Running fuzz target tests'
- @./testTargets $(srcdir)
+ @./testTargets
+
+# Seed corpus
+
+genSeed_SOURCES = genSeed.c fuzz.c
+
+# XPath fuzzer
-fuzz-xpath: xpath$(EXEEXT)
+seed/xpath.stamp: genSeed$(EXEEXT)
+ @mkdir -p seed/xpath
+ @./genSeed$(EXEEXT) xpath "$(top_srcdir)/tests"
+ @touch seed/xpath.stamp
+
+xpath_SOURCES = xpath.c fuzz.c fuzz.h
+xpath_LDFLAGS = -fsanitize=fuzzer
+
+fuzz-xpath: xpath$(EXEEXT) seed/xpath.stamp
@mkdir -p corpus/xpath
./xpath$(EXEEXT) \
- -max_len=256 \
-dict=$(srcdir)/xpath.dict \
corpus/xpath $(srcdir)/seed/xpath
-fuzz-xslt: xslt$(EXEEXT)
+# XSLT fuzzer
+
+seed/xslt.stamp: genSeed$(EXEEXT)
+ @mkdir -p seed/xslt
+ @./genSeed$(EXEEXT) xslt "$(top_srcdir)/tests"
+ @touch seed/xslt.stamp
+
+xslt_SOURCES = xslt.c fuzz.c fuzz.h
+xslt_LDFLAGS = -fsanitize=fuzzer
+
+fuzz-xslt: xslt$(EXEEXT) seed/xslt.stamp
@mkdir -p corpus/xslt
./xslt$(EXEEXT) \
-dict=$(srcdir)/xslt.dict \
diff --git a/tests/fuzz/fuzz.c b/tests/fuzz/fuzz.c
index cf1e2383..6912941a 100644
--- a/tests/fuzz/fuzz.c
+++ b/tests/fuzz/fuzz.c
@@ -4,14 +4,13 @@
* See Copyright for the status of this software.
*/
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include "fuzz.h"
-
-#include <libxml/tree.h>
#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <libxslt/extensions.h>
@@ -22,6 +21,7 @@
#include <libxslt/xsltInternals.h>
#include <libxslt/xsltutils.h>
#include <libexslt/exslt.h>
+#include "fuzz.h"
#if defined(_WIN32)
#define DIR_SEP '\\'
@@ -29,10 +29,9 @@
#define DIR_SEP '/'
#endif
-static xmlDocPtr doc;
-static xsltSecurityPrefsPtr sec;
+static xsltSecurityPrefsPtr globalSec;
+static xsltStylesheetPtr globalStyle;
static xsltTransformContextPtr tctxt;
-static xmlHashTablePtr saxonExtHash;
static void
xsltFuzzXmlErrorFunc(void *vctxt, const char *msg ATTRIBUTE_UNUSED, ...) {
@@ -51,6 +50,8 @@ xsltFuzzXsltErrorFunc(void *vctxt ATTRIBUTE_UNUSED,
static void
xsltFuzzInit(void) {
+ xmlFuzzMemSetup();
+
/* Init libxml2, libxslt and libexslt */
xmlInitParser();
xsltInit();
@@ -61,54 +62,17 @@ xsltFuzzInit(void) {
xsltSetGenericErrorFunc(NULL, xsltFuzzXsltErrorFunc);
/* Disallow I/O */
- sec = xsltNewSecurityPrefs();
- xsltSetSecurityPrefs(sec, XSLT_SECPREF_READ_FILE, xsltSecurityForbid);
- xsltSetSecurityPrefs(sec, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid);
- xsltSetSecurityPrefs(sec, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid);
- xsltSetSecurityPrefs(sec, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid);
- xsltSetSecurityPrefs(sec, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid);
-}
-
-static xmlDocPtr
-xsltFuzzLoadDoc(const char *argv0, const char *dir, const char *filename) {
- char *path;
-
- if (dir != NULL) {
- path = malloc(strlen(dir) + 1 + strlen(filename) + 1);
- sprintf(path, "%s/%s", dir, filename);
- doc = xmlReadFile(path, NULL, 0);
- if (doc == NULL)
- fprintf(stderr, "Error: unable to parse file '%s' in '%s'\n",
- filename, dir);
- } else {
- const char *end;
- size_t dirLen;
-
- end = strrchr(argv0, DIR_SEP);
- dirLen = (end == NULL) ? 0 : end - argv0 + 1;
- path = malloc(dirLen + strlen(filename) + 1);
- memcpy(path, argv0, dirLen);
- path[dirLen] = '\0';
- strcat(path, filename);
- doc = xmlReadFile(path, NULL, 0);
-
- if (doc == NULL && dirLen > 0) {
- /* Binary might be in .libs, try parent directory */
- path[dirLen-1] = 0;
- end = strrchr(path, DIR_SEP);
- dirLen = (end == NULL) ? 0 : end - path + 1;
- path[dirLen] = '\0';
- strcat(path, filename);
- doc = xmlReadFile(path, NULL, 0);
- }
-
- if (doc == NULL)
- fprintf(stderr, "Error: unable to parse file '%s'\n", filename);
- }
-
- free(path);
-
- return doc;
+ globalSec = xsltNewSecurityPrefs();
+ xsltSetSecurityPrefs(globalSec, XSLT_SECPREF_READ_FILE,
+ xsltSecurityForbid);
+ xsltSetSecurityPrefs(globalSec, XSLT_SECPREF_WRITE_FILE,
+ xsltSecurityForbid);
+ xsltSetSecurityPrefs(globalSec, XSLT_SECPREF_CREATE_DIRECTORY,
+ xsltSecurityForbid);
+ xsltSetSecurityPrefs(globalSec, XSLT_SECPREF_READ_NETWORK,
+ xsltSecurityForbid);
+ xsltSetSecurityPrefs(globalSec, XSLT_SECPREF_WRITE_NETWORK,
+ xsltSecurityForbid);
}
/* XPath fuzzer
@@ -147,22 +111,44 @@ xsltFuzzLoadDoc(const char *argv0, const char *dir, const char *filename) {
*/
int
-xsltFuzzXPathInit(int *argc_p ATTRIBUTE_UNUSED, char ***argv_p,
- const char *dir) {
- const char *xmlFilename = "xpath.xml";
- xsltStylesheetPtr style;
- xmlXPathContextPtr xpctxt;
-
+xsltFuzzXPathInit(void) {
xsltFuzzInit();
+ globalStyle = xsltNewStylesheet();
+ return(0);
+}
+
+xmlXPathObjectPtr
+xsltFuzzXPath(const char *data, size_t size) {
+ xmlXPathContextPtr xpctxt = NULL;
+ xmlXPathObjectPtr xpathObj = NULL;
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ const char *xpathExpr, *xml;
+ size_t maxAllocs, xmlSize;
+
+ xmlFuzzDataInit(data, size);
- /* Load XML document */
- doc = xsltFuzzLoadDoc((*argv_p)[0], dir, xmlFilename);
+ maxAllocs = xmlFuzzReadInt(4) % (size + 1);
+ xpathExpr = xmlFuzzReadString(NULL);
+ xml = xmlFuzzReadString(&xmlSize);
+
+ /* Recovery mode allows more input to be fuzzed. */
+ doc = xmlReadMemory(xml, xmlSize, NULL, NULL, XML_PARSE_RECOVER);
if (doc == NULL)
- return -1;
+ goto error;
+ root = xmlDocGetRootElement(doc);
+ if (root != NULL) {
+ xmlNewNs(root, BAD_CAST "a", BAD_CAST "a");
+ xmlNewNs(root, BAD_CAST "b", BAD_CAST "b");
+ xmlNewNs(root, BAD_CAST "c", BAD_CAST "c");
+ }
- style = xsltNewStylesheet();
- tctxt = xsltNewTransformContext(style, doc);
- xsltSetCtxtSecurityPrefs(sec, tctxt);
+ tctxt = xsltNewTransformContext(globalStyle, doc);
+ if (tctxt == NULL) {
+ xmlFreeDoc(doc);
+ goto error;
+ }
+ xsltSetCtxtSecurityPrefs(globalSec, tctxt);
/*
* Some extension functions need the current instruction.
@@ -175,16 +161,13 @@ xsltFuzzXPathInit(int *argc_p ATTRIBUTE_UNUSED, char ***argv_p,
*/
tctxt->inst = xmlDocGetRootElement(doc);
- saxonExtHash = (xmlHashTablePtr)
- xsltStyleGetExtData(style, SAXON_NAMESPACE);
-
/* Set up XPath context */
xpctxt = tctxt->xpathCtxt;
/* Resource limits to avoid timeouts and call stack overflows */
xpctxt->opLimit = 500000;
- /* Test namespaces used in xpath.xml */
+ /* Test namespaces */
xmlXPathRegisterNs(xpctxt, BAD_CAST "a", BAD_CAST "a");
xmlXPathRegisterNs(xpctxt, BAD_CAST "b", BAD_CAST "b");
xmlXPathRegisterNs(xpctxt, BAD_CAST "c", BAD_CAST "c");
@@ -208,53 +191,26 @@ xsltFuzzXPathInit(int *argc_p ATTRIBUTE_UNUSED, char ***argv_p,
xpctxt, BAD_CAST "n",
xmlXPathEval(BAD_CAST "//node() | /*/*/namespace::*", xpctxt));
- return 0;
-}
-
-xmlXPathObjectPtr
-xsltFuzzXPath(const char *data, size_t size) {
- xmlXPathContextPtr xpctxt = tctxt->xpathCtxt;
- xmlChar *xpathExpr;
-
- /* Null-terminate */
- xpathExpr = malloc(size + 1);
- memcpy(xpathExpr, data, size);
- xpathExpr[size] = 0;
-
/* Compile and return early if the expression is invalid */
- xmlXPathCompExprPtr compExpr = xmlXPathCtxtCompile(xpctxt, xpathExpr);
- free(xpathExpr);
+ xmlXPathCompExprPtr compExpr = xmlXPathCtxtCompile(xpctxt,
+ (const xmlChar *) xpathExpr);
if (compExpr == NULL)
- return NULL;
+ goto error;
/* Initialize XPath evaluation context and evaluate */
- xpctxt->node = (xmlNodePtr) doc; /* Maybe test different context nodes? */
+ xmlFuzzMemSetLimit(maxAllocs);
+ /* Maybe test different context nodes? */
+ xpctxt->node = (xmlNodePtr) doc;
xpctxt->contextSize = 1;
xpctxt->proximityPosition = 1;
xpctxt->opCount = 0;
- xmlXPathObjectPtr xpathObj = xmlXPathCompiledEval(compExpr, xpctxt);
+ xpathObj = xmlXPathCompiledEval(compExpr, xpctxt);
xmlXPathFreeCompExpr(compExpr);
- /* Clean object cache */
- xmlXPathContextSetCache(xpctxt, 0, 0, 0);
- xmlXPathContextSetCache(xpctxt, 1, -1, 0);
-
- /* Clean dictionaries */
- if (xmlDictSize(tctxt->dict) > 0) {
- xmlDictFree(tctxt->dict);
- xmlDictFree(tctxt->style->dict);
- tctxt->style->dict = xmlDictCreate();
- tctxt->dict = xmlDictCreateSub(tctxt->style->dict);
- }
-
- /* Clean saxon:expression cache */
- if (xmlHashSize(saxonExtHash) > 0) {
- /* There doesn't seem to be a cheaper way with the public API. */
- xsltShutdownCtxtExts(tctxt);
- xsltInitCtxtExts(tctxt);
- saxonExtHash = (xmlHashTablePtr)
- xsltStyleGetExtData(tctxt->style, SAXON_NAMESPACE);
- }
+error:
+ xmlFuzzMemSetLimit(0);
+ xmlXPathRegisteredNsCleanup(xpctxt);
+ xmlFuzzDataCleanup();
return xpathObj;
}
@@ -263,23 +219,21 @@ void
xsltFuzzXPathFreeObject(xmlXPathObjectPtr obj) {
xmlXPathFreeObject(obj);
- /* Some XSLT extension functions create RVTs. */
- xsltFreeRVTs(tctxt);
+ if (tctxt != NULL) {
+ xmlDocPtr doc = tctxt->document->doc;
+
+ xsltFreeTransformContext(tctxt);
+ tctxt = NULL;
+ xmlFreeDoc(doc);
+ }
}
void
xsltFuzzXPathCleanup(void) {
- xsltStylesheetPtr style = tctxt->style;
-
- xmlXPathRegisteredNsCleanup(tctxt->xpathCtxt);
- xsltFreeSecurityPrefs(sec);
- sec = NULL;
- xsltFreeTransformContext(tctxt);
- tctxt = NULL;
- xsltFreeStylesheet(style);
- style = NULL;
- xmlFreeDoc(doc);
- doc = NULL;
+ xsltFreeSecurityPrefs(globalSec);
+ globalSec = NULL;
+ xsltFreeStylesheet(globalStyle);
+ globalStyle = NULL;
}
/*
@@ -298,59 +252,78 @@ xsltFuzzXPathCleanup(void) {
*/
int
-xsltFuzzXsltInit(int *argc_p ATTRIBUTE_UNUSED, char ***argv_p,
- const char *dir) {
- const char *xmlFilename = "xslt.xml";
-
+xsltFuzzXsltInit(void) {
xsltFuzzInit();
-
- /* Load XML document */
- doc = xsltFuzzLoadDoc((*argv_p)[0], dir, xmlFilename);
- if (doc == NULL)
- return -1;
-
- return 0;
+ xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
+ return(0);
}
xmlChar *
xsltFuzzXslt(const char *data, size_t size) {
- xmlDocPtr xsltDoc;
- xmlDocPtr result;
- xmlNodePtr xsltRoot;
- xsltStylesheetPtr sheet;
- xsltTransformContextPtr ctxt;
+ const char *xsltBuffer, *xsltUrl, *docBuffer, *docUrl;
+ xmlDocPtr xsltDoc = NULL, doc = NULL;
+ xmlDocPtr result = NULL;
+ xmlNodePtr root;
+ xsltStylesheetPtr sheet = NULL;
+ xsltTransformContextPtr ctxt = NULL;
xmlChar *ret = NULL;
+ size_t xsltSize, docSize, maxAllocs;
int retLen;
- xsltDoc = xmlReadMemory(data, size, NULL, NULL, 0);
+ xmlFuzzDataInit(data, size);
+ maxAllocs = xmlFuzzReadInt(4) % (size + 1);
+
+ xmlFuzzReadEntities();
+ xsltBuffer = xmlFuzzMainEntity(&xsltSize);
+ xsltUrl = xmlFuzzMainUrl();
+ docBuffer = xmlFuzzSecondaryEntity(&docSize);
+ docUrl = xmlFuzzSecondaryUrl();
+ if ((xsltBuffer == NULL) || (docBuffer == NULL))
+ goto exit;
+
+ doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, XSLT_PARSE_OPTIONS);
+ if (doc == NULL)
+ goto exit;
+
+ xsltDoc = xmlReadMemory(xsltBuffer, xsltSize, xsltUrl, NULL,
+ XSLT_PARSE_OPTIONS);
if (xsltDoc == NULL)
- return NULL;
- xsltRoot = xmlDocGetRootElement(xsltDoc);
- xmlNewNs(xsltRoot, EXSLT_COMMON_NAMESPACE, BAD_CAST "exsl");
- xmlNewNs(xsltRoot, EXSLT_COMMON_NAMESPACE, BAD_CAST "exslt");
- xmlNewNs(xsltRoot, EXSLT_CRYPTO_NAMESPACE, BAD_CAST "crypto");
- xmlNewNs(xsltRoot, EXSLT_DATE_NAMESPACE, BAD_CAST "date");
- xmlNewNs(xsltRoot, EXSLT_DYNAMIC_NAMESPACE, BAD_CAST "dyn");
- xmlNewNs(xsltRoot, EXSLT_MATH_NAMESPACE, BAD_CAST "math");
- xmlNewNs(xsltRoot, EXSLT_SETS_NAMESPACE, BAD_CAST "set");
- xmlNewNs(xsltRoot, EXSLT_STRINGS_NAMESPACE, BAD_CAST "str");
- xmlNewNs(xsltRoot, SAXON_NAMESPACE, BAD_CAST "saxon");
+ goto exit;
+ root = xmlDocGetRootElement(xsltDoc);
+ if (root != NULL) {
+ xmlNewNs(root, XSLT_NAMESPACE, BAD_CAST "x");
+ xmlNewNs(root, EXSLT_COMMON_NAMESPACE, BAD_CAST "exsl");
+ xmlNewNs(root, EXSLT_COMMON_NAMESPACE, BAD_CAST "exslt");
+ xmlNewNs(root, EXSLT_CRYPTO_NAMESPACE, BAD_CAST "crypto");
+ xmlNewNs(root, EXSLT_DATE_NAMESPACE, BAD_CAST "date");
+ xmlNewNs(root, EXSLT_DYNAMIC_NAMESPACE, BAD_CAST "dyn");
+ xmlNewNs(root, EXSLT_MATH_NAMESPACE, BAD_CAST "math");
+ xmlNewNs(root, EXSLT_SETS_NAMESPACE, BAD_CAST "set");
+ xmlNewNs(root, EXSLT_STRINGS_NAMESPACE, BAD_CAST "str");
+ xmlNewNs(root, SAXON_NAMESPACE, BAD_CAST "saxon");
+ }
+ xmlFuzzMemSetLimit(maxAllocs);
sheet = xsltNewStylesheet();
- if (sheet == NULL) {
- xmlFreeDoc(xsltDoc);
- return NULL;
- }
+ if (sheet == NULL)
+ goto exit;
sheet->xpathCtxt->opLimit = 100000;
sheet->xpathCtxt->opCount = 0;
- if (xsltParseStylesheetUser(sheet, xsltDoc) != 0) {
- xsltFreeStylesheet(sheet);
- xmlFreeDoc(xsltDoc);
- return NULL;
+ if (xsltParseStylesheetUser(sheet, xsltDoc) != 0)
+ goto exit;
+ xsltDoc = NULL;
+
+ root = xmlDocGetRootElement(doc);
+ if (root != NULL) {
+ xmlNewNs(root, BAD_CAST "a", BAD_CAST "a");
+ xmlNewNs(root, BAD_CAST "b", BAD_CAST "b");
+ xmlNewNs(root, BAD_CAST "c", BAD_CAST "c");
}
ctxt = xsltNewTransformContext(sheet, doc);
- xsltSetCtxtSecurityPrefs(sec, ctxt);
+ if (ctxt == NULL)
+ goto exit;
+ xsltSetCtxtSecurityPrefs(globalSec, ctxt);
ctxt->maxTemplateDepth = 100;
ctxt->opLimit = 20000;
ctxt->xpathCtxt->opLimit = 100000;
@@ -360,17 +333,408 @@ xsltFuzzXslt(const char *data, size_t size) {
if (result != NULL)
xsltSaveResultToString(&ret, &retLen, result, sheet);
+exit:
+ xmlFuzzMemSetLimit(0);
xmlFreeDoc(result);
xsltFreeTransformContext(ctxt);
xsltFreeStylesheet(sheet);
+ xmlFreeDoc(xsltDoc);
+ xmlFreeDoc(doc);
+ xmlFuzzDataCleanup();
return ret;
}
void
xsltFuzzXsltCleanup(void) {
- xsltFreeSecurityPrefs(sec);
- sec = NULL;
- xmlFreeDoc(doc);
- doc = NULL;
+ xsltFreeSecurityPrefs(globalSec);
+ globalSec = NULL;
+}
+
+/*
+ * Utility functions, copied from libxml2
+ */
+
+typedef struct {
+ const char *data;
+ size_t size;
+} xmlFuzzEntityInfo;
+
+/* Single static instance for now */
+static struct {
+ /* Original data */
+ const char *data;
+ size_t size;
+
+ /* Remaining data */
+ const char *ptr;
+ size_t remaining;
+
+ /* Buffer for unescaped strings */
+ char *outBuf;
+ char *outPtr; /* Free space at end of buffer */
+
+ xmlHashTablePtr entities; /* Maps URLs to xmlFuzzEntityInfos */
+
+ /* The first entity is the main entity. */
+ const char *mainUrl;
+ xmlFuzzEntityInfo *mainEntity;
+ const char *secondaryUrl;
+ xmlFuzzEntityInfo *secondaryEntity;
+} fuzzData;
+
+size_t fuzzNumAllocs;
+size_t fuzzMaxAllocs;
+
+/**
+ * xmlFuzzErrorFunc:
+ *
+ * An error function that simply discards all errors.
+ */
+void
+xmlFuzzErrorFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED,
+ ...) {
+}
+
+/*
+ * Malloc failure injection.
+ *
+ * Quick tip to debug complicated issues: Increase MALLOC_OFFSET until
+ * the crash disappears (or a different issue is triggered). Then set
+ * the offset to the highest value that produces a crash and set
+ * MALLOC_ABORT to 1 to see which failed memory allocation causes the
+ * issue.
+ */
+
+#define XML_FUZZ_MALLOC_OFFSET 0
+#define XML_FUZZ_MALLOC_ABORT 0
+
+static void *
+xmlFuzzMalloc(size_t size) {
+ if (fuzzMaxAllocs > 0) {
+ if (fuzzNumAllocs >= fuzzMaxAllocs - 1)
+#if XML_FUZZ_MALLOC_ABORT
+ abort();
+#else
+ return(NULL);
+#endif
+ fuzzNumAllocs += 1;
+ }
+ return malloc(size);
+}
+
+static void *
+xmlFuzzRealloc(void *ptr, size_t size) {
+ if (fuzzMaxAllocs > 0) {
+ if (fuzzNumAllocs >= fuzzMaxAllocs - 1)
+#if XML_FUZZ_MALLOC_ABORT
+ abort();
+#else
+ return(NULL);
+#endif
+ fuzzNumAllocs += 1;
+ }
+ return realloc(ptr, size);
+}
+
+void
+xmlFuzzMemSetup(void) {
+ xmlMemSetup(free, xmlFuzzMalloc, xmlFuzzRealloc, xmlMemStrdup);
+}
+
+void
+xmlFuzzMemSetLimit(size_t limit) {
+ fuzzNumAllocs = 0;
+ fuzzMaxAllocs = limit ? limit + XML_FUZZ_MALLOC_OFFSET : 0;
+}
+
+/**
+ * xmlFuzzDataInit:
+ *
+ * Initialize fuzz data provider.
+ */
+void
+xmlFuzzDataInit(const char *data, size_t size) {
+ fuzzData.data = data;
+ fuzzData.size = size;
+ fuzzData.ptr = data;
+ fuzzData.remaining = size;
+
+ fuzzData.outBuf = xmlMalloc(size + 1);
+ fuzzData.outPtr = fuzzData.outBuf;
+
+ fuzzData.entities = xmlHashCreate(8);
+ fuzzData.mainUrl = NULL;
+ fuzzData.mainEntity = NULL;
+ fuzzData.secondaryUrl = NULL;
+ fuzzData.secondaryEntity = NULL;
+}
+
+/**
+ * xmlFuzzDataFree:
+ *
+ * Cleanup fuzz data provider.
+ */
+void
+xmlFuzzDataCleanup(void) {
+ xmlFree(fuzzData.outBuf);
+ xmlHashFree(fuzzData.entities, xmlHashDefaultDeallocator);
+}
+
+/**
+ * xmlFuzzWriteInt:
+ * @out: output file
+ * @v: integer to write
+ * @size: size of integer in bytes
+ *
+ * Write an integer to the fuzz data.
+ */
+void
+xmlFuzzWriteInt(FILE *out, size_t v, int size) {
+ int shift;
+
+ while (size > (int) sizeof(size_t)) {
+ putc(0, out);
+ size--;
+ }
+
+ shift = size * 8;
+ while (shift > 0) {
+ shift -= 8;
+ putc((v >> shift) & 255, out);
+ }
+}
+
+/**
+ * xmlFuzzReadInt:
+ * @size: size of integer in bytes
+ *
+ * Read an integer from the fuzz data.
+ */
+size_t
+xmlFuzzReadInt(int size) {
+ size_t ret = 0;
+
+ while ((size > 0) && (fuzzData.remaining > 0)) {
+ unsigned char c = (unsigned char) *fuzzData.ptr++;
+ fuzzData.remaining--;
+ ret = (ret << 8) | c;
+ size--;
+ }
+
+ return ret;
+}
+
+/**
+ * xmlFuzzReadRemaining:
+ * @size: size of string in bytes
+ *
+ * Read remaining bytes from fuzz data.
+ */
+const char *
+xmlFuzzReadRemaining(size_t *size) {
+ const char *ret = fuzzData.ptr;
+
+ *size = fuzzData.remaining;
+ fuzzData.ptr += fuzzData.remaining;
+ fuzzData.remaining = 0;
+
+ return(ret);
+}
+
+/*
+ * xmlFuzzWriteString:
+ * @out: output file
+ * @str: string to write
+ *
+ * Write a random-length string to file in a format similar to
+ * FuzzedDataProvider. Backslash followed by newline marks the end of the
+ * string. Two backslashes are used to escape a backslash.
+ */
+void
+xmlFuzzWriteString(FILE *out, const char *str) {
+ for (; *str; str++) {
+ int c = (unsigned char) *str;
+ putc(c, out);
+ if (c == '\\')
+ putc(c, out);
+ }
+ putc('\\', out);
+ putc('\n', out);
+}
+
+/**
+ * xmlFuzzReadString:
+ * @size: size of string in bytes
+ *
+ * Read a random-length string from the fuzz data.
+ *
+ * The format is similar to libFuzzer's FuzzedDataProvider but treats
+ * backslash followed by newline as end of string. This makes the fuzz data
+ * more readable. A backslash character is escaped with another backslash.
+ *
+ * Returns a zero-terminated string or NULL if the fuzz data is exhausted.
+ */
+const char *
+xmlFuzzReadString(size_t *size) {
+ const char *out = fuzzData.outPtr;
+
+ while (fuzzData.remaining > 0) {
+ int c = *fuzzData.ptr++;
+ fuzzData.remaining--;
+
+ if ((c == '\\') && (fuzzData.remaining > 0)) {
+ int c2 = *fuzzData.ptr;
+
+ if (c2 == '\n') {
+ fuzzData.ptr++;
+ fuzzData.remaining--;
+ if (size != NULL)
+ *size = fuzzData.outPtr - out;
+ *fuzzData.outPtr++ = '\0';
+ return(out);
+ }
+ if (c2 == '\\') {
+ fuzzData.ptr++;
+ fuzzData.remaining--;
+ }
+ }
+
+ *fuzzData.outPtr++ = c;
+ }
+
+ if (fuzzData.outPtr > out) {
+ if (size != NULL)
+ *size = fuzzData.outPtr - out;
+ *fuzzData.outPtr++ = '\0';
+ return(out);
+ }
+
+ if (size != NULL)
+ *size = 0;
+ return(NULL);
+}
+
+/**
+ * xmlFuzzReadEntities:
+ *
+ * Read entities like the main XML file, external DTDs, external parsed
+ * entities from fuzz data.
+ */
+void
+xmlFuzzReadEntities(void) {
+ size_t num = 0;
+
+ while (1) {
+ const char *url, *entity;
+ size_t entitySize;
+ xmlFuzzEntityInfo *entityInfo;
+
+ url = xmlFuzzReadString(NULL);
+ if (url == NULL) break;
+
+ entity = xmlFuzzReadString(&entitySize);
+ if (entity == NULL) break;
+
+ if (xmlHashLookup(fuzzData.entities, (xmlChar *)url) == NULL) {
+ entityInfo = xmlMalloc(sizeof(xmlFuzzEntityInfo));
+ if (entityInfo == NULL)
+ break;
+ entityInfo->data = entity;
+ entityInfo->size = entitySize;
+
+ xmlHashAddEntry(fuzzData.entities, (xmlChar *)url, entityInfo);
+
+ if (num == 0) {
+ fuzzData.mainUrl = url;
+ fuzzData.mainEntity = entityInfo;
+ } else if (num == 1) {
+ fuzzData.secondaryUrl = url;
+ fuzzData.secondaryEntity = entityInfo;
+ }
+
+ num++;
+ }
+ }
+}
+
+/**
+ * xmlFuzzMainUrl:
+ *
+ * Returns the main URL.
+ */
+const char *
+xmlFuzzMainUrl(void) {
+ return(fuzzData.mainUrl);
+}
+
+/**
+ * xmlFuzzMainEntity:
+ * @size: size of the main entity in bytes
+ *
+ * Returns the main entity.
+ */
+const char *
+xmlFuzzMainEntity(size_t *size) {
+ if (fuzzData.mainEntity == NULL)
+ return(NULL);
+ *size = fuzzData.mainEntity->size;
+ return(fuzzData.mainEntity->data);
+}
+
+/**
+ * xmlFuzzSecondaryUrl:
+ *
+ * Returns the secondary URL.
+ */
+const char *
+xmlFuzzSecondaryUrl(void) {
+ return(fuzzData.secondaryUrl);
+}
+
+/**
+ * xmlFuzzSecondaryEntity:
+ * @size: size of the secondary entity in bytes
+ *
+ * Returns the secondary entity.
+ */
+const char *
+xmlFuzzSecondaryEntity(size_t *size) {
+ if (fuzzData.secondaryEntity == NULL)
+ return(NULL);
+ *size = fuzzData.secondaryEntity->size;
+ return(fuzzData.secondaryEntity->data);
+}
+
+/**
+ * xmlFuzzEntityLoader:
+ *
+ * The entity loader for fuzz data.
+ */
+xmlParserInputPtr
+xmlFuzzEntityLoader(const char *URL, const char *ID ATTRIBUTE_UNUSED,
+ xmlParserCtxtPtr ctxt) {
+ xmlParserInputPtr input;
+ xmlFuzzEntityInfo *entity;
+
+ if (URL == NULL)
+ return(NULL);
+ entity = xmlHashLookup(fuzzData.entities, (xmlChar *) URL);
+ if (entity == NULL)
+ return(NULL);
+
+ input = xmlNewInputStream(ctxt);
+ if (input == NULL)
+ return(NULL);
+ input->filename = (char *) xmlCharStrdup(URL);
+ input->buf = xmlParserInputBufferCreateMem(entity->data, entity->size,
+ XML_CHAR_ENCODING_NONE);
+ if (input->buf == NULL) {
+ xmlFreeInputStream(input);
+ return(NULL);
+ }
+ input->base = input->cur = xmlBufContent(input->buf->buffer);
+ input->end = input->base + entity->size;
+
+ return input;
}
diff --git a/tests/fuzz/fuzz.h b/tests/fuzz/fuzz.h
index 7dff3dbe..3ff81ca6 100644
--- a/tests/fuzz/fuzz.h
+++ b/tests/fuzz/fuzz.h
@@ -12,7 +12,13 @@
#include <libxml/xpath.h>
int
-xsltFuzzXPathInit(int *argc_p, char ***argv_p, const char *dir);
+LLVMFuzzerInitialize(int *argc, char ***argv);
+
+int
+LLVMFuzzerTestOneInput(const char *data, size_t size);
+
+int
+xsltFuzzXPathInit(void);
xmlXPathObjectPtr
xsltFuzzXPath(const char *data, size_t size);
@@ -24,7 +30,7 @@ void
xsltFuzzXPathCleanup(void);
int
-xsltFuzzXsltInit(int *argc_p, char ***argv_p, const char *dir);
+xsltFuzzXsltInit(void);
xmlChar *
xsltFuzzXslt(const char *data, size_t size);
@@ -32,4 +38,55 @@ xsltFuzzXslt(const char *data, size_t size);
void
xsltFuzzXsltCleanup(void);
+/* Utility functions */
+
+void
+xmlFuzzErrorFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED,
+ ...);
+
+void
+xmlFuzzMemSetup(void);
+
+void
+xmlFuzzMemSetLimit(size_t limit);
+
+void
+xmlFuzzDataInit(const char *data, size_t size);
+
+void
+xmlFuzzDataCleanup(void);
+
+void
+xmlFuzzWriteInt(FILE *out, size_t v, int size);
+
+size_t
+xmlFuzzReadInt(int size);
+
+const char *
+xmlFuzzReadRemaining(size_t *size);
+
+void
+xmlFuzzWriteString(FILE *out, const char *str);
+
+const char *
+xmlFuzzReadString(size_t *size);
+
+void
+xmlFuzzReadEntities(void);
+
+const char *
+xmlFuzzMainUrl(void);
+
+const char *
+xmlFuzzMainEntity(size_t *size);
+
+const char *
+xmlFuzzSecondaryUrl(void);
+
+const char *
+xmlFuzzSecondaryEntity(size_t *size);
+
+xmlParserInputPtr
+xmlFuzzEntityLoader(const char *URL, const char *ID, xmlParserCtxtPtr ctxt);
+
#endif
diff --git a/tests/fuzz/genSeed.c b/tests/fuzz/genSeed.c
new file mode 100644
index 00000000..235da992
--- /dev/null
+++ b/tests/fuzz/genSeed.c
@@ -0,0 +1,487 @@
+/*
+ * genSeed.c: Generate the seed corpora for fuzzing.
+ *
+ * See Copyright for the status of this software.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <glob.h>
+#include <libgen.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <libxml/parserInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltutils.h>
+#include "fuzz.h"
+
+#define PATH_SIZE 500
+#define SEED_BUF_SIZE 16384
+
+typedef int
+(*fileFunc)(const char *base, FILE *out);
+
+typedef int
+(*mainFunc)(const char *testsDir);
+
+static struct {
+ FILE *out;
+ xmlHashTablePtr entities; /* Maps URLs to xmlFuzzEntityInfos */
+ xmlExternalEntityLoader oldLoader;
+ fileFunc processFile;
+ const char *fuzzer;
+ const char *docDir;
+ char cwd[PATH_SIZE];
+} globalData;
+
+/*
+ * A custom entity loader that writes all external DTDs or entities to a
+ * single file in the format expected by xmlFuzzEntityLoader.
+ */
+static xmlParserInputPtr
+fuzzEntityRecorder(const char *URL, const char *ID, xmlParserCtxtPtr ctxt) {
+ xmlParserInputPtr in;
+ xmlChar *data;
+ static const int chunkSize = 16384;
+ int len;
+
+ in = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+ if (in == NULL)
+ return(NULL);
+
+ if (globalData.entities == NULL) {
+ globalData.entities = xmlHashCreate(4);
+ } else if (xmlHashLookup(globalData.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);
+
+ data = xmlStrdup(xmlBufContent(in->buf->buffer));
+ if (data == NULL) {
+ fprintf(stderr, "Error allocating entity data\n");
+ xmlFreeInputStream(in);
+ return(NULL);
+ }
+
+ xmlFreeInputStream(in);
+
+ xmlHashAddEntry(globalData.entities, (const xmlChar *) URL, data);
+
+ return(xmlNoNetExternalEntityLoader(URL, ID, ctxt));
+}
+
+static void
+fuzzRecorderInit(FILE *out) {
+ globalData.out = out;
+ globalData.entities = xmlHashCreate(8);
+ globalData.oldLoader = xmlGetExternalEntityLoader();
+ xmlSetExternalEntityLoader(fuzzEntityRecorder);
+}
+
+static void
+fuzzRecorderWriteAndFree(void *entry, const xmlChar *file) {
+ char *data = entry;
+ xmlFuzzWriteString(globalData.out, (const char *) file);
+ xmlFuzzWriteString(globalData.out, data);
+ xmlFree(data);
+}
+
+static void
+fuzzRecorderWrite(const char *file) {
+ xmlHashRemoveEntry(globalData.entities, (const xmlChar *) file,
+ fuzzRecorderWriteAndFree);
+}
+
+static void
+fuzzRecorderCleanup() {
+ xmlSetExternalEntityLoader(globalData.oldLoader);
+ /* Write remaining entities (in random order). */
+ xmlHashFree(globalData.entities, fuzzRecorderWriteAndFree);
+ globalData.out = NULL;
+ globalData.entities = NULL;
+ globalData.oldLoader = NULL;
+}
+
+static int
+processXslt(const char *sheetFile, FILE *out) {
+ struct stat statbuf;
+ xsltStylesheetPtr sheet;
+ xmlDocPtr doc;
+ char docFile[PATH_SIZE];
+ char base[PATH_SIZE] = "";
+ size_t len, size;
+
+ len = strlen(sheetFile);
+ if ((len < 5) || (len >= PATH_SIZE) ||
+ (strcmp(sheetFile + len - 4, ".xsl") != 0)) {
+ fprintf(stderr, "invalid stylesheet file: %s\n", sheetFile);
+ return(-1);
+ }
+ strncat(base, sheetFile, len - 4);
+
+ if (globalData.docDir == NULL) {
+ size = snprintf(docFile, sizeof(docFile), "%s.xml", base);
+ } else {
+ size = snprintf(docFile, sizeof(docFile), "%s/%s.xml",
+ globalData.docDir, base);
+ }
+ if (size >= sizeof(docFile)) {
+ fprintf(stderr, "creating pattern failed\n");
+ return(-1);
+ }
+
+ /* Document might not exist, for example with imported stylesheets. */
+ if (stat(docFile, &statbuf) != 0)
+ return(-1);
+
+ /* Malloc limit. */
+ xmlFuzzWriteInt(out, 0, 4);
+
+ fuzzRecorderInit(out);
+
+ sheet = xsltParseStylesheetFile(BAD_CAST sheetFile);
+ doc = xmlReadFile(docFile, NULL, XSLT_PARSE_OPTIONS);
+ xmlFreeDoc(xsltApplyStylesheet(sheet, doc, NULL));
+ xmlFreeDoc(doc);
+ xsltFreeStylesheet(sheet);
+
+ fuzzRecorderWrite(sheetFile);
+ fuzzRecorderWrite(docFile);
+ fuzzRecorderCleanup();
+
+ return(0);
+}
+
+static int
+processPattern(const char *pattern) {
+ glob_t globbuf;
+ int ret = 0;
+ int res;
+ size_t i;
+
+ res = glob(pattern, 0, NULL, &globbuf);
+ if (res == GLOB_NOMATCH)
+ return(0);
+ if (res != 0) {
+ fprintf(stderr, "couldn't match pattern %s\n", pattern);
+ return(-1);
+ }
+
+ for (i = 0; i < globbuf.gl_pathc; i++) {
+ struct stat statbuf;
+ char outPath[PATH_SIZE];
+ char *dirBuf = NULL;
+ char *baseBuf = NULL;
+ const char *path, *dir, *base;
+ FILE *out = NULL;
+ int dirChanged = 0;
+ size_t size;
+
+ res = -1;
+ path = globbuf.gl_pathv[i];
+
+ if ((stat(path, &statbuf) != 0) || (!S_ISREG(statbuf.st_mode)))
+ continue;
+
+ dirBuf = (char *) xmlCharStrdup(path);
+ baseBuf = (char *) xmlCharStrdup(path);
+ if ((dirBuf == NULL) || (baseBuf == NULL)) {
+ fprintf(stderr, "memory allocation failed\n");
+ ret = -1;
+ goto error;
+ }
+ dir = dirname(dirBuf);
+ base = basename(baseBuf);
+
+ size = snprintf(outPath, sizeof(outPath), "seed/%s/%s",
+ globalData.fuzzer, base);
+ if (size >= sizeof(outPath)) {
+ fprintf(stderr, "creating path failed\n");
+ ret = -1;
+ goto error;
+ }
+ out = fopen(outPath, "wb");
+ if (out == NULL) {
+ fprintf(stderr, "couldn't open %s for writing\n", outPath);
+ ret = -1;
+ goto error;
+ }
+ if (chdir(dir) != 0) {
+ fprintf(stderr, "couldn't chdir to %s\n", dir);
+ ret = -1;
+ goto error;
+ }
+ dirChanged = 1;
+ res = globalData.processFile(base, out);
+
+error:
+ if ((dirChanged) && (chdir(globalData.cwd) != 0)) {
+ fprintf(stderr, "couldn't chdir to %s\n", globalData.cwd);
+ ret = -1;
+ break;
+ }
+ if (out != NULL) {
+ fclose(out);
+ if (res != 0) {
+ unlink(outPath);
+ ret = -1;
+ }
+ }
+ xmlFree(dirBuf);
+ xmlFree(baseBuf);
+ }
+
+ globfree(&globbuf);
+ return(ret);
+}
+
+static int
+processTestDir(const char *testsDir, const char *subDir, const char *docDir) {
+ char pattern[PATH_SIZE];
+ size_t size;
+
+ size = snprintf(pattern, sizeof(pattern), "%s/%s/*.xsl",
+ testsDir, subDir);
+ if (size >= sizeof(pattern)) {
+ fprintf(stderr, "creating pattern failed\n");
+ return -1;
+ }
+
+ globalData.docDir = docDir;
+ return processPattern(pattern);
+}
+
+static int
+processTests(const char *testsDir) {
+ processTestDir(testsDir, "REC", NULL);
+ processTestDir(testsDir, "general", "../docs");
+ processTestDir(testsDir, "exslt/*", NULL);
+
+ return 0;
+}
+
+static int
+processXPath(const char *testsDir ATTRIBUTE_UNUSED) {
+#define UTF8_Auml "\xC3\x84"
+#define UTF8_szlig "\xC3\x9F"
+#define UTF8_ALPHA "\xCE\xB1"
+#define UTF8_DEJA "d\xC3\xA9j\xC3\xA0"
+ static const char *xml =
+ "<?pi content?>\n"
+ "<a xmlns:a=\"a\">\n"
+ " <b xmlns:b=\"b\" a=\"1\" id=\"b\">\n"
+ " <c b=\"2\">" UTF8_Auml "rger</c>\n"
+ " <b:d b=\"3\">text</b:d>\n"
+ " <!-- comment -->\n"
+ " <a:b b=\"4\">" UTF8_szlig "&#x1f600;</a:b>\n"
+ " <b:c a=\"4\"><![CDATA[text]]></b:c>\n"
+ " </b>\n"
+ " <?pi content?>\n"
+ " <a:e xmlns:c=\"c\" a=\"" UTF8_ALPHA "\">\n"
+ " <c:d b=\"2\"/>\n"
+ " <a:c>99</a:c>\n"
+ " <e a=\"2\">content</e>\n"
+ " </a:e>\n"
+ " <b/>\n"
+ " <a:a/>\n"
+ " <!-- comment -->\n"
+ "</a>\n";
+ static const char *exprs[] = {
+ "crypto:md4('a')",
+ "crypto:md5('a')",
+ "crypto:rc4_decrypt(crypto:rc4_encrypt('key','msg'))",
+ "crypto:sha1('a')",
+ "date:add('2016-01-01T12:00:00','-P1Y2M3DT10H30M45S')",
+ "date:add-duration('-P1Y2M3DT10H30M45S','-P1Y2M3DT10H30M45S')",
+ "date:date('2016-01-01T12:00:00')",
+ "date:date-time()",
+ "date:day-abbreviation('2016-01-01T12:00:00')",
+ "date:day-in-month('2016-01-01T12:00:00')",
+ "date:day-in-week('2016-01-01T12:00:00')",
+ "date:day-in-year('2016-01-01T12:00:00')",
+ "date:day-name('2016-01-01T12:00:00')",
+ "date:day-of-week-in-month('2016-01-01T12:00:00')",
+ "date:difference('1999-06-10T20:03:48','2016-01-01T12:00:00')",
+ "date:duration('1234567890')",
+ "date:format-date('2016-01-01T12:00:00','GyyyyMMwwWWDDddFFEaHHkkKKhhMMssSSSzZ')",
+ "date:hour-in-day('2016-01-01T12:00:00')",
+ "date:leap-year('2016-01-01T12:00:00')",
+ "date:minute-in-hour('2016-01-01T12:00:00')",
+ "date:month-abbreviation('2016-01-01T12:00:00')",
+ "date:month-in-year('2016-01-01T12:00:00')",
+ "date:month-name('2016-01-01T12:00:00')",
+ "date:parse-date('20160101120000','yyyyMMddkkmmss')",
+ "date:second-in-minute('2016-01-01T12:00:00')",
+ "date:seconds('2016-01-01T12:00:00')",
+ "date:sum(str:split('-P1Y2M3DT10H30M45S,-P1Y2M3DT10H30M45S,P999999999S',','))",
+ "date:time('2016-01-01T12:00:00')",
+ "date:week-in-month('2016-01-01T12:00:00')",
+ "date:week-in-year('2016-01-01T12:00:00')",
+ "date:year('2016-01-01T12:00:00')",
+ "dyn:evaluate('1+1')",
+ "dyn:map(//*,'.')",
+ "(1.1+-24.5)*0.8-(25div3.5)mod0.2",
+ "/a/b/c/text()|//e/c:d/@b",
+ "(//*[@*][1])[1]",
+ "exsl:node-set($n)",
+ "exsl:node-set('s')",
+ "exsl:object-type(1)",
+ "boolean(.)",
+ "ceiling(.)",
+ "concat(.,'a')",
+ "contains(.,'e')",
+ "count(.)",
+ "false()",
+ "floor(.)",
+ "id(.)",
+ "lang(.)",
+ "last()",
+ "local-name(.)",
+ "name(.)",
+ "namespace-uri(.)",
+ "normalize-space(.)",
+ "not(.)",
+ "number(.)",
+ "number('1.0')",
+ "position()",
+ "round(.)",
+ "starts-with(.,'t')",
+ "string-length(.)",
+ "string(.)",
+ "string(1.0)",
+ "substring(.,2,3)",
+ "substring-after(.,'e')",
+ "substring-before(.,'e')",
+ "sum(*)",
+ "translate(.,'e','a')",
+ "true()",
+ "math:abs(-1.5)",
+ "math:acos(-0.5)",
+ "math:asin(-0.5)",
+ "math:atan(-0.5)",
+ "math:atan2(-1.5,-1.5)",
+ "math:constant('E',20)",
+ "math:cos(-1.5)",
+ "math:exp(-1.5)",
+ "math:highest(str:split('1.2,-0.5,-2.2e8,-0.1e-5',','))",
+ "math:log(2.0)",
+ "math:lowest(str:split('1.2,-0.5,-2.2e8,-0.1e-5',','))",
+ "math:max(str:split('1.2,-0.5,-2.2e8,-0.1e-5',','))",
+ "math:min(str:split('1.2,-0.5,-2.2e8,-0.1e-5',','))",
+ "math:power(2.0,0.5)",
+ "math:random()",
+ "math:sin(-1.5)",
+ "math:sqrt(2.0)",
+ "math:tan(-1.5)",
+ "saxon:eval(saxon:expression('1+1'))",
+ "saxon:evaluate('1+1')",
+ "saxon:line-number()",
+ "saxon:line-number(*)",
+ "saxon:systemId()",
+ "set:difference(//*,//a:*)",
+ "set:distinct(//*)",
+ "set:has-same-node(//*,//a:*)",
+ "set:intersection(//*,//a:*)",
+ "set:leading(//*,/*/*[3])",
+ "set:trailing(//*,/*/*[2])",
+ "str:align('" UTF8_DEJA "','--------','center')",
+ "str:align('" UTF8_DEJA "','--------','left')",
+ "str:align('" UTF8_DEJA "','--------','right')",
+ "str:concat(str:split('ab,cd,ef',','))",
+ "str:decode-uri('%41%00%2d')",
+ "str:encode-uri(';/?:@&=+$,[]',true())",
+ "str:encode-uri('|<>',false())",
+ "str:padding(81,' ')",
+ "str:replace('abcdefgh',str:split('a,c,e,g',','),str:split('w,x,y,z',','))",
+ "str:split('a, sim, lis',', ')",
+ "str:tokenize('2016-01-01T12:00:00','-T:')",
+ "current()",
+ "document('')",
+ "element-available('exsl:document')",
+ "format-number(1.0,'##,##,00.00##')",
+ "format-number(1.0,'#.#;-0.0%')",
+ "function-available('exsl:node-set')",
+ "generate-id(.)",
+ "system-property('xsl:version')",
+ "unparsed-entity-uri('a')"
+ };
+ size_t numExprs = sizeof(exprs) / sizeof(*exprs);
+ size_t i, size;
+ int ret = 0;
+
+ for (i = 0; i < numExprs; i++) {
+ char outPath[PATH_SIZE];
+ FILE *out;
+
+ size = snprintf(outPath, sizeof(outPath), "seed/xpath/%03d", (int) i);
+ if (size >= PATH_SIZE) {
+ ret = -1;
+ continue;
+ }
+ out = fopen(outPath, "wb");
+ if (out == NULL) {
+ ret = -1;
+ continue;
+ }
+ /* Memory limit. */
+ xmlFuzzWriteInt(out, 0, 4);
+ xmlFuzzWriteString(out, exprs[i]);
+ xmlFuzzWriteString(out, xml);
+
+ fclose(out);
+ }
+
+ return(ret);
+}
+
+int
+main(int argc, const char **argv) {
+ mainFunc process = processTests;
+ const char *fuzzer;
+ int ret = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "usage: genSeed [FUZZER] [PATTERN...]\n");
+ return(1);
+ }
+
+ xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
+ xsltSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
+
+ fuzzer = argv[1];
+ if (strcmp(fuzzer, "xslt") == 0) {
+ globalData.processFile = processXslt;
+ } else if (strcmp(fuzzer, "xpath") == 0) {
+ process = processXPath;
+ } else {
+ fprintf(stderr, "unknown fuzzer %s\n", fuzzer);
+ return(1);
+ }
+ globalData.fuzzer = fuzzer;
+
+ if (getcwd(globalData.cwd, PATH_SIZE) == NULL) {
+ fprintf(stderr, "couldn't get current directory\n");
+ return(1);
+ }
+
+ process(argv[2]);
+
+ return(ret);
+}
+
diff --git a/tests/fuzz/seed/xpath/crypto_md4 b/tests/fuzz/seed/xpath/crypto_md4
deleted file mode 100644
index af26aed1..00000000
--- a/tests/fuzz/seed/xpath/crypto_md4
+++ /dev/null
@@ -1 +0,0 @@
-crypto:md4('a')
diff --git a/tests/fuzz/seed/xpath/crypto_md5 b/tests/fuzz/seed/xpath/crypto_md5
deleted file mode 100644
index e0af6d39..00000000
--- a/tests/fuzz/seed/xpath/crypto_md5
+++ /dev/null
@@ -1 +0,0 @@
-crypto:md5('a')
diff --git a/tests/fuzz/seed/xpath/crypto_rc4_decrypt b/tests/fuzz/seed/xpath/crypto_rc4_decrypt
deleted file mode 100644
index fe346720..00000000
--- a/tests/fuzz/seed/xpath/crypto_rc4_decrypt
+++ /dev/null
@@ -1 +0,0 @@
-crypto:rc4_decrypt(crypto:rc4_encrypt('key','msg'))
diff --git a/tests/fuzz/seed/xpath/crypto_sha1 b/tests/fuzz/seed/xpath/crypto_sha1
deleted file mode 100644
index a139200d..00000000
--- a/tests/fuzz/seed/xpath/crypto_sha1
+++ /dev/null
@@ -1 +0,0 @@
-crypto:sha1('a')
diff --git a/tests/fuzz/seed/xpath/date_add b/tests/fuzz/seed/xpath/date_add
deleted file mode 100644
index e12bd62c..00000000
--- a/tests/fuzz/seed/xpath/date_add
+++ /dev/null
@@ -1 +0,0 @@
-date:add('2016-01-01T12:00:00','-P1Y2M3DT10H30M45S')
diff --git a/tests/fuzz/seed/xpath/date_add_duration b/tests/fuzz/seed/xpath/date_add_duration
deleted file mode 100644
index 3add82f3..00000000
--- a/tests/fuzz/seed/xpath/date_add_duration
+++ /dev/null
@@ -1 +0,0 @@
-date:add-duration('-P1Y2M3DT10H30M45S','-P1Y2M3DT10H30M45S')
diff --git a/tests/fuzz/seed/xpath/date_date b/tests/fuzz/seed/xpath/date_date
deleted file mode 100644
index db7eb0fb..00000000
--- a/tests/fuzz/seed/xpath/date_date
+++ /dev/null
@@ -1 +0,0 @@
-date:date('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_date_time b/tests/fuzz/seed/xpath/date_date_time
deleted file mode 100644
index 56c80c79..00000000
--- a/tests/fuzz/seed/xpath/date_date_time
+++ /dev/null
@@ -1 +0,0 @@
-date:date-time()
diff --git a/tests/fuzz/seed/xpath/date_day_abbreviation b/tests/fuzz/seed/xpath/date_day_abbreviation
deleted file mode 100644
index ea19a5d4..00000000
--- a/tests/fuzz/seed/xpath/date_day_abbreviation
+++ /dev/null
@@ -1 +0,0 @@
-date:day-abbreviation('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_day_in_month b/tests/fuzz/seed/xpath/date_day_in_month
deleted file mode 100644
index 2b21b611..00000000
--- a/tests/fuzz/seed/xpath/date_day_in_month
+++ /dev/null
@@ -1 +0,0 @@
-date:day-in-month('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_day_in_week b/tests/fuzz/seed/xpath/date_day_in_week
deleted file mode 100644
index 78343b04..00000000
--- a/tests/fuzz/seed/xpath/date_day_in_week
+++ /dev/null
@@ -1 +0,0 @@
-date:day-in-week('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_day_in_year b/tests/fuzz/seed/xpath/date_day_in_year
deleted file mode 100644
index 32e55743..00000000
--- a/tests/fuzz/seed/xpath/date_day_in_year
+++ /dev/null
@@ -1 +0,0 @@
-date:day-in-year('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_day_name b/tests/fuzz/seed/xpath/date_day_name
deleted file mode 100644
index 69d66aee..00000000
--- a/tests/fuzz/seed/xpath/date_day_name
+++ /dev/null
@@ -1 +0,0 @@
-date:day-name('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_day_of_week_in_month b/tests/fuzz/seed/xpath/date_day_of_week_in_month
deleted file mode 100644
index e2525bd7..00000000
--- a/tests/fuzz/seed/xpath/date_day_of_week_in_month
+++ /dev/null
@@ -1 +0,0 @@
-date:day-of-week-in-month('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_difference b/tests/fuzz/seed/xpath/date_difference
deleted file mode 100644
index deb5b9d1..00000000
--- a/tests/fuzz/seed/xpath/date_difference
+++ /dev/null
@@ -1 +0,0 @@
-date:difference('1999-06-10T20:03:48','2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_duration b/tests/fuzz/seed/xpath/date_duration
deleted file mode 100644
index 1c8f4acb..00000000
--- a/tests/fuzz/seed/xpath/date_duration
+++ /dev/null
@@ -1 +0,0 @@
-date:duration('1234567890')
diff --git a/tests/fuzz/seed/xpath/date_format_date b/tests/fuzz/seed/xpath/date_format_date
deleted file mode 100644
index 7025e1d5..00000000
--- a/tests/fuzz/seed/xpath/date_format_date
+++ /dev/null
@@ -1 +0,0 @@
-date:format-date('2016-01-01T12:00:00','GyyyyMMwwWWDDddFFEaHHkkKKhhMMssSSSzZ')
diff --git a/tests/fuzz/seed/xpath/date_hour_in_day b/tests/fuzz/seed/xpath/date_hour_in_day
deleted file mode 100644
index 68ed1f00..00000000
--- a/tests/fuzz/seed/xpath/date_hour_in_day
+++ /dev/null
@@ -1 +0,0 @@
-date:hour-in-day('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_leap_year b/tests/fuzz/seed/xpath/date_leap_year
deleted file mode 100644
index 4f7b98da..00000000
--- a/tests/fuzz/seed/xpath/date_leap_year
+++ /dev/null
@@ -1 +0,0 @@
-date:leap-year('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_minute_in_hour b/tests/fuzz/seed/xpath/date_minute_in_hour
deleted file mode 100644
index 865fbc25..00000000
--- a/tests/fuzz/seed/xpath/date_minute_in_hour
+++ /dev/null
@@ -1 +0,0 @@
-date:minute-in-hour('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_month_abbreviation b/tests/fuzz/seed/xpath/date_month_abbreviation
deleted file mode 100644
index 89a2e2c4..00000000
--- a/tests/fuzz/seed/xpath/date_month_abbreviation
+++ /dev/null
@@ -1 +0,0 @@
-date:month-abbreviation('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_month_in_year b/tests/fuzz/seed/xpath/date_month_in_year
deleted file mode 100644
index 07c0c12d..00000000
--- a/tests/fuzz/seed/xpath/date_month_in_year
+++ /dev/null
@@ -1 +0,0 @@
-date:month-in-year('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_month_name b/tests/fuzz/seed/xpath/date_month_name
deleted file mode 100644
index 7da78e79..00000000
--- a/tests/fuzz/seed/xpath/date_month_name
+++ /dev/null
@@ -1 +0,0 @@
-date:month-name('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_parse_date b/tests/fuzz/seed/xpath/date_parse_date
deleted file mode 100644
index cea782cc..00000000
--- a/tests/fuzz/seed/xpath/date_parse_date
+++ /dev/null
@@ -1 +0,0 @@
-date:parse-date('20160101120000','yyyyMMddkkmmss')
diff --git a/tests/fuzz/seed/xpath/date_second_in_minute b/tests/fuzz/seed/xpath/date_second_in_minute
deleted file mode 100644
index 2574fa74..00000000
--- a/tests/fuzz/seed/xpath/date_second_in_minute
+++ /dev/null
@@ -1 +0,0 @@
-date:second-in-minute('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_seconds b/tests/fuzz/seed/xpath/date_seconds
deleted file mode 100644
index 48ec1c2a..00000000
--- a/tests/fuzz/seed/xpath/date_seconds
+++ /dev/null
@@ -1 +0,0 @@
-date:seconds('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_sum b/tests/fuzz/seed/xpath/date_sum
deleted file mode 100644
index 39500251..00000000
--- a/tests/fuzz/seed/xpath/date_sum
+++ /dev/null
@@ -1 +0,0 @@
-date:sum(str:split('-P1Y2M3DT10H30M45S,-P1Y2M3DT10H30M45S,P999999999S',','))
diff --git a/tests/fuzz/seed/xpath/date_time b/tests/fuzz/seed/xpath/date_time
deleted file mode 100644
index 3333638c..00000000
--- a/tests/fuzz/seed/xpath/date_time
+++ /dev/null
@@ -1 +0,0 @@
-date:time('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_week_in_month b/tests/fuzz/seed/xpath/date_week_in_month
deleted file mode 100644
index 415ed927..00000000
--- a/tests/fuzz/seed/xpath/date_week_in_month
+++ /dev/null
@@ -1 +0,0 @@
-date:week-in-month('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_week_in_year b/tests/fuzz/seed/xpath/date_week_in_year
deleted file mode 100644
index baf0c2cd..00000000
--- a/tests/fuzz/seed/xpath/date_week_in_year
+++ /dev/null
@@ -1 +0,0 @@
-date:week-in-year('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/date_year b/tests/fuzz/seed/xpath/date_year
deleted file mode 100644
index b615fde4..00000000
--- a/tests/fuzz/seed/xpath/date_year
+++ /dev/null
@@ -1 +0,0 @@
-date:year('2016-01-01T12:00:00')
diff --git a/tests/fuzz/seed/xpath/dyn_evaluate b/tests/fuzz/seed/xpath/dyn_evaluate
deleted file mode 100644
index cb0f284b..00000000
--- a/tests/fuzz/seed/xpath/dyn_evaluate
+++ /dev/null
@@ -1 +0,0 @@
-dyn:evaluate('1+1')
diff --git a/tests/fuzz/seed/xpath/dyn_map b/tests/fuzz/seed/xpath/dyn_map
deleted file mode 100644
index 361ddb39..00000000
--- a/tests/fuzz/seed/xpath/dyn_map
+++ /dev/null
@@ -1 +0,0 @@
-dyn:map(//*,'.')
diff --git a/tests/fuzz/seed/xpath/expr_arith b/tests/fuzz/seed/xpath/expr_arith
deleted file mode 100644
index bc4813df..00000000
--- a/tests/fuzz/seed/xpath/expr_arith
+++ /dev/null
@@ -1 +0,0 @@
-(1.1+-24.5)*0.8-(25div3.5)mod0.2
diff --git a/tests/fuzz/seed/xpath/expr_location_path b/tests/fuzz/seed/xpath/expr_location_path
deleted file mode 100644
index 789255c2..00000000
--- a/tests/fuzz/seed/xpath/expr_location_path
+++ /dev/null
@@ -1 +0,0 @@
-/a/b/c/text()|//e/c:d/@b
diff --git a/tests/fuzz/seed/xpath/expr_predicate b/tests/fuzz/seed/xpath/expr_predicate
deleted file mode 100644
index 191b3051..00000000
--- a/tests/fuzz/seed/xpath/expr_predicate
+++ /dev/null
@@ -1 +0,0 @@
-(//*[@*][1])[1]
diff --git a/tests/fuzz/seed/xpath/exsl_node_set_1 b/tests/fuzz/seed/xpath/exsl_node_set_1
deleted file mode 100644
index a27992a5..00000000
--- a/tests/fuzz/seed/xpath/exsl_node_set_1
+++ /dev/null
@@ -1 +0,0 @@
-exsl:node-set($n)
diff --git a/tests/fuzz/seed/xpath/exsl_node_set_2 b/tests/fuzz/seed/xpath/exsl_node_set_2
deleted file mode 100644
index 10b276c5..00000000
--- a/tests/fuzz/seed/xpath/exsl_node_set_2
+++ /dev/null
@@ -1 +0,0 @@
-exsl:node-set('s')
diff --git a/tests/fuzz/seed/xpath/exsl_object_type b/tests/fuzz/seed/xpath/exsl_object_type
deleted file mode 100644
index 2a3784a2..00000000
--- a/tests/fuzz/seed/xpath/exsl_object_type
+++ /dev/null
@@ -1 +0,0 @@
-exsl:object-type(1)
diff --git a/tests/fuzz/seed/xpath/func_boolean b/tests/fuzz/seed/xpath/func_boolean
deleted file mode 100644
index 409bec66..00000000
--- a/tests/fuzz/seed/xpath/func_boolean
+++ /dev/null
@@ -1 +0,0 @@
-boolean(.)
diff --git a/tests/fuzz/seed/xpath/func_ceiling b/tests/fuzz/seed/xpath/func_ceiling
deleted file mode 100644
index f23305db..00000000
--- a/tests/fuzz/seed/xpath/func_ceiling
+++ /dev/null
@@ -1 +0,0 @@
-ceiling(.)
diff --git a/tests/fuzz/seed/xpath/func_concat b/tests/fuzz/seed/xpath/func_concat
deleted file mode 100644
index b6c9a1b1..00000000
--- a/tests/fuzz/seed/xpath/func_concat
+++ /dev/null
@@ -1 +0,0 @@
-concat(.,'a')
diff --git a/tests/fuzz/seed/xpath/func_contains b/tests/fuzz/seed/xpath/func_contains
deleted file mode 100644
index ed18a39c..00000000
--- a/tests/fuzz/seed/xpath/func_contains
+++ /dev/null
@@ -1 +0,0 @@
-contains(.,'e')
diff --git a/tests/fuzz/seed/xpath/func_count b/tests/fuzz/seed/xpath/func_count
deleted file mode 100644
index 3fea95c0..00000000
--- a/tests/fuzz/seed/xpath/func_count
+++ /dev/null
@@ -1 +0,0 @@
-count(.)
diff --git a/tests/fuzz/seed/xpath/func_false b/tests/fuzz/seed/xpath/func_false
deleted file mode 100644
index f9e9b505..00000000
--- a/tests/fuzz/seed/xpath/func_false
+++ /dev/null
@@ -1 +0,0 @@
-false()
diff --git a/tests/fuzz/seed/xpath/func_floor b/tests/fuzz/seed/xpath/func_floor
deleted file mode 100644
index 6c0d2db0..00000000
--- a/tests/fuzz/seed/xpath/func_floor
+++ /dev/null
@@ -1 +0,0 @@
-floor(.)
diff --git a/tests/fuzz/seed/xpath/func_id b/tests/fuzz/seed/xpath/func_id
deleted file mode 100644
index 9c29ea0d..00000000
--- a/tests/fuzz/seed/xpath/func_id
+++ /dev/null
@@ -1 +0,0 @@
-id(.)
diff --git a/tests/fuzz/seed/xpath/func_lang b/tests/fuzz/seed/xpath/func_lang
deleted file mode 100644
index 1ff69fd2..00000000
--- a/tests/fuzz/seed/xpath/func_lang
+++ /dev/null
@@ -1 +0,0 @@
-lang(.)
diff --git a/tests/fuzz/seed/xpath/func_last b/tests/fuzz/seed/xpath/func_last
deleted file mode 100644
index 06e7e03f..00000000
--- a/tests/fuzz/seed/xpath/func_last
+++ /dev/null
@@ -1 +0,0 @@
-last()
diff --git a/tests/fuzz/seed/xpath/func_local_name b/tests/fuzz/seed/xpath/func_local_name
deleted file mode 100644
index 1a0193b3..00000000
--- a/tests/fuzz/seed/xpath/func_local_name
+++ /dev/null
@@ -1 +0,0 @@
-local-name(.)
diff --git a/tests/fuzz/seed/xpath/func_name b/tests/fuzz/seed/xpath/func_name
deleted file mode 100644
index 6bce7bf5..00000000
--- a/tests/fuzz/seed/xpath/func_name
+++ /dev/null
@@ -1 +0,0 @@
-name(.)
diff --git a/tests/fuzz/seed/xpath/func_namespace_uri b/tests/fuzz/seed/xpath/func_namespace_uri
deleted file mode 100644
index 649a382c..00000000
--- a/tests/fuzz/seed/xpath/func_namespace_uri
+++ /dev/null
@@ -1 +0,0 @@
-namespace-uri(.)
diff --git a/tests/fuzz/seed/xpath/func_normalize_space b/tests/fuzz/seed/xpath/func_normalize_space
deleted file mode 100644
index 84f6777f..00000000
--- a/tests/fuzz/seed/xpath/func_normalize_space
+++ /dev/null
@@ -1 +0,0 @@
-normalize-space(.)
diff --git a/tests/fuzz/seed/xpath/func_not b/tests/fuzz/seed/xpath/func_not
deleted file mode 100644
index 44bc806e..00000000
--- a/tests/fuzz/seed/xpath/func_not
+++ /dev/null
@@ -1 +0,0 @@
-not(.)
diff --git a/tests/fuzz/seed/xpath/func_number_node b/tests/fuzz/seed/xpath/func_number_node
deleted file mode 100644
index c1f1c489..00000000
--- a/tests/fuzz/seed/xpath/func_number_node
+++ /dev/null
@@ -1 +0,0 @@
-number(.)
diff --git a/tests/fuzz/seed/xpath/func_number_str b/tests/fuzz/seed/xpath/func_number_str
deleted file mode 100644
index 31a8d993..00000000
--- a/tests/fuzz/seed/xpath/func_number_str
+++ /dev/null
@@ -1 +0,0 @@
-number('1.0')
diff --git a/tests/fuzz/seed/xpath/func_position b/tests/fuzz/seed/xpath/func_position
deleted file mode 100644
index ec993e8b..00000000
--- a/tests/fuzz/seed/xpath/func_position
+++ /dev/null
@@ -1 +0,0 @@
-position()
diff --git a/tests/fuzz/seed/xpath/func_round b/tests/fuzz/seed/xpath/func_round
deleted file mode 100644
index 54315843..00000000
--- a/tests/fuzz/seed/xpath/func_round
+++ /dev/null
@@ -1 +0,0 @@
-round(.)
diff --git a/tests/fuzz/seed/xpath/func_starts_with b/tests/fuzz/seed/xpath/func_starts_with
deleted file mode 100644
index 1a9f1e98..00000000
--- a/tests/fuzz/seed/xpath/func_starts_with
+++ /dev/null
@@ -1 +0,0 @@
-starts-with(.,'t')
diff --git a/tests/fuzz/seed/xpath/func_string_length b/tests/fuzz/seed/xpath/func_string_length
deleted file mode 100644
index 26e107fe..00000000
--- a/tests/fuzz/seed/xpath/func_string_length
+++ /dev/null
@@ -1 +0,0 @@
-string-length(.)
diff --git a/tests/fuzz/seed/xpath/func_string_node b/tests/fuzz/seed/xpath/func_string_node
deleted file mode 100644
index e85c11ca..00000000
--- a/tests/fuzz/seed/xpath/func_string_node
+++ /dev/null
@@ -1 +0,0 @@
-string(.)
diff --git a/tests/fuzz/seed/xpath/func_string_num b/tests/fuzz/seed/xpath/func_string_num
deleted file mode 100644
index 6c9fe040..00000000
--- a/tests/fuzz/seed/xpath/func_string_num
+++ /dev/null
@@ -1 +0,0 @@
-string(1.0)
diff --git a/tests/fuzz/seed/xpath/func_substring b/tests/fuzz/seed/xpath/func_substring
deleted file mode 100644
index f069f81e..00000000
--- a/tests/fuzz/seed/xpath/func_substring
+++ /dev/null
@@ -1 +0,0 @@
-substring(.,2,3)
diff --git a/tests/fuzz/seed/xpath/func_substring_after b/tests/fuzz/seed/xpath/func_substring_after
deleted file mode 100644
index 1bbecc93..00000000
--- a/tests/fuzz/seed/xpath/func_substring_after
+++ /dev/null
@@ -1 +0,0 @@
-substring-after(.,'e')
diff --git a/tests/fuzz/seed/xpath/func_substring_before b/tests/fuzz/seed/xpath/func_substring_before
deleted file mode 100644
index fcb14f14..00000000
--- a/tests/fuzz/seed/xpath/func_substring_before
+++ /dev/null
@@ -1 +0,0 @@
-substring-before(.,'e')
diff --git a/tests/fuzz/seed/xpath/func_sum b/tests/fuzz/seed/xpath/func_sum
deleted file mode 100644
index d110af82..00000000
--- a/tests/fuzz/seed/xpath/func_sum
+++ /dev/null
@@ -1 +0,0 @@
-sum(*)
diff --git a/tests/fuzz/seed/xpath/func_translate b/tests/fuzz/seed/xpath/func_translate
deleted file mode 100644
index 18fe731a..00000000
--- a/tests/fuzz/seed/xpath/func_translate
+++ /dev/null
@@ -1 +0,0 @@
-translate(.,'e','a')
diff --git a/tests/fuzz/seed/xpath/func_true b/tests/fuzz/seed/xpath/func_true
deleted file mode 100644
index c7fa7136..00000000
--- a/tests/fuzz/seed/xpath/func_true
+++ /dev/null
@@ -1 +0,0 @@
-true()
diff --git a/tests/fuzz/seed/xpath/math_abs b/tests/fuzz/seed/xpath/math_abs
deleted file mode 100644
index a56bfbf9..00000000
--- a/tests/fuzz/seed/xpath/math_abs
+++ /dev/null
@@ -1 +0,0 @@
-math:abs(-1.5)
diff --git a/tests/fuzz/seed/xpath/math_acos b/tests/fuzz/seed/xpath/math_acos
deleted file mode 100644
index 79d181c8..00000000
--- a/tests/fuzz/seed/xpath/math_acos
+++ /dev/null
@@ -1 +0,0 @@
-math:acos(-0.5)
diff --git a/tests/fuzz/seed/xpath/math_asin b/tests/fuzz/seed/xpath/math_asin
deleted file mode 100644
index 919d6eb4..00000000
--- a/tests/fuzz/seed/xpath/math_asin
+++ /dev/null
@@ -1 +0,0 @@
-math:asin(-0.5)
diff --git a/tests/fuzz/seed/xpath/math_atan b/tests/fuzz/seed/xpath/math_atan
deleted file mode 100644
index 40e6610f..00000000
--- a/tests/fuzz/seed/xpath/math_atan
+++ /dev/null
@@ -1 +0,0 @@
-math:atan(-0.5)
diff --git a/tests/fuzz/seed/xpath/math_atan2 b/tests/fuzz/seed/xpath/math_atan2
deleted file mode 100644
index c02562ba..00000000
--- a/tests/fuzz/seed/xpath/math_atan2
+++ /dev/null
@@ -1 +0,0 @@
-math:atan2(-1.5,-1.5)
diff --git a/tests/fuzz/seed/xpath/math_constant b/tests/fuzz/seed/xpath/math_constant
deleted file mode 100644
index bf6fe12b..00000000
--- a/tests/fuzz/seed/xpath/math_constant
+++ /dev/null
@@ -1 +0,0 @@
-math:constant('E',20)
diff --git a/tests/fuzz/seed/xpath/math_cos b/tests/fuzz/seed/xpath/math_cos
deleted file mode 100644
index 2a95639c..00000000
--- a/tests/fuzz/seed/xpath/math_cos
+++ /dev/null
@@ -1 +0,0 @@
-math:cos(-1.5)
diff --git a/tests/fuzz/seed/xpath/math_exp b/tests/fuzz/seed/xpath/math_exp
deleted file mode 100644
index 5ddf4b6a..00000000
--- a/tests/fuzz/seed/xpath/math_exp
+++ /dev/null
@@ -1 +0,0 @@
-math:exp(-1.5)
diff --git a/tests/fuzz/seed/xpath/math_highest b/tests/fuzz/seed/xpath/math_highest
deleted file mode 100644
index 7a64ae57..00000000
--- a/tests/fuzz/seed/xpath/math_highest
+++ /dev/null
@@ -1 +0,0 @@
-math:highest(str:split('1.2,-0.5,-2.2e8,-0.1e-5',','))
diff --git a/tests/fuzz/seed/xpath/math_log b/tests/fuzz/seed/xpath/math_log
deleted file mode 100644
index 260e6bc5..00000000
--- a/tests/fuzz/seed/xpath/math_log
+++ /dev/null
@@ -1 +0,0 @@
-math:log(2.0)
diff --git a/tests/fuzz/seed/xpath/math_lowest b/tests/fuzz/seed/xpath/math_lowest
deleted file mode 100644
index 5590bee8..00000000
--- a/tests/fuzz/seed/xpath/math_lowest
+++ /dev/null
@@ -1 +0,0 @@
-math:lowest(str:split('1.2,-0.5,-2.2e8,-0.1e-5',','))
diff --git a/tests/fuzz/seed/xpath/math_max b/tests/fuzz/seed/xpath/math_max
deleted file mode 100644
index 47e745b6..00000000
--- a/tests/fuzz/seed/xpath/math_max
+++ /dev/null
@@ -1 +0,0 @@
-math:max(str:split('1.2,-0.5,-2.2e8,-0.1e-5',','))
diff --git a/tests/fuzz/seed/xpath/math_min b/tests/fuzz/seed/xpath/math_min
deleted file mode 100644
index 3265d2c2..00000000
--- a/tests/fuzz/seed/xpath/math_min
+++ /dev/null
@@ -1 +0,0 @@
-math:min(str:split('1.2,-0.5,-2.2e8,-0.1e-5',','))
diff --git a/tests/fuzz/seed/xpath/math_power b/tests/fuzz/seed/xpath/math_power
deleted file mode 100644
index 3c7591c7..00000000
--- a/tests/fuzz/seed/xpath/math_power
+++ /dev/null
@@ -1 +0,0 @@
-math:power(2.0,0.5)
diff --git a/tests/fuzz/seed/xpath/math_random b/tests/fuzz/seed/xpath/math_random
deleted file mode 100644
index 9c6cca42..00000000
--- a/tests/fuzz/seed/xpath/math_random
+++ /dev/null
@@ -1 +0,0 @@
-math:random()
diff --git a/tests/fuzz/seed/xpath/math_sin b/tests/fuzz/seed/xpath/math_sin
deleted file mode 100644
index ba2e6bb4..00000000
--- a/tests/fuzz/seed/xpath/math_sin
+++ /dev/null
@@ -1 +0,0 @@
-math:sin(-1.5)
diff --git a/tests/fuzz/seed/xpath/math_sqrt b/tests/fuzz/seed/xpath/math_sqrt
deleted file mode 100644
index 36f71c43..00000000
--- a/tests/fuzz/seed/xpath/math_sqrt
+++ /dev/null
@@ -1 +0,0 @@
-math:sqrt(2.0)
diff --git a/tests/fuzz/seed/xpath/math_tan b/tests/fuzz/seed/xpath/math_tan
deleted file mode 100644
index 2329ae52..00000000
--- a/tests/fuzz/seed/xpath/math_tan
+++ /dev/null
@@ -1 +0,0 @@
-math:tan(-1.5)
diff --git a/tests/fuzz/seed/xpath/saxon_eval b/tests/fuzz/seed/xpath/saxon_eval
deleted file mode 100644
index 0f520105..00000000
--- a/tests/fuzz/seed/xpath/saxon_eval
+++ /dev/null
@@ -1 +0,0 @@
-saxon:eval(saxon:expression('1+1'))
diff --git a/tests/fuzz/seed/xpath/saxon_evaluate b/tests/fuzz/seed/xpath/saxon_evaluate
deleted file mode 100644
index b8102265..00000000
--- a/tests/fuzz/seed/xpath/saxon_evaluate
+++ /dev/null
@@ -1 +0,0 @@
-saxon:evaluate('1+1')
diff --git a/tests/fuzz/seed/xpath/saxon_line_number_0 b/tests/fuzz/seed/xpath/saxon_line_number_0
deleted file mode 100644
index 5052bc2a..00000000
--- a/tests/fuzz/seed/xpath/saxon_line_number_0
+++ /dev/null
@@ -1 +0,0 @@
-saxon:line-number()
diff --git a/tests/fuzz/seed/xpath/saxon_line_number_1 b/tests/fuzz/seed/xpath/saxon_line_number_1
deleted file mode 100644
index 542705cf..00000000
--- a/tests/fuzz/seed/xpath/saxon_line_number_1
+++ /dev/null
@@ -1 +0,0 @@
-saxon:line-number(*)
diff --git a/tests/fuzz/seed/xpath/saxon_systemId b/tests/fuzz/seed/xpath/saxon_systemId
deleted file mode 100644
index 2c548b51..00000000
--- a/tests/fuzz/seed/xpath/saxon_systemId
+++ /dev/null
@@ -1 +0,0 @@
-saxon:systemId()
diff --git a/tests/fuzz/seed/xpath/set_difference b/tests/fuzz/seed/xpath/set_difference
deleted file mode 100644
index 2e8678ba..00000000
--- a/tests/fuzz/seed/xpath/set_difference
+++ /dev/null
@@ -1 +0,0 @@
-set:difference(//*,//a:*)
diff --git a/tests/fuzz/seed/xpath/set_distinct b/tests/fuzz/seed/xpath/set_distinct
deleted file mode 100644
index c7dc183b..00000000
--- a/tests/fuzz/seed/xpath/set_distinct
+++ /dev/null
@@ -1 +0,0 @@
-set:distinct(//*)
diff --git a/tests/fuzz/seed/xpath/set_has_same_node b/tests/fuzz/seed/xpath/set_has_same_node
deleted file mode 100644
index 83096062..00000000
--- a/tests/fuzz/seed/xpath/set_has_same_node
+++ /dev/null
@@ -1 +0,0 @@
-set:has-same-node(//*,//a:*)
diff --git a/tests/fuzz/seed/xpath/set_intersection b/tests/fuzz/seed/xpath/set_intersection
deleted file mode 100644
index 8f2d97f5..00000000
--- a/tests/fuzz/seed/xpath/set_intersection
+++ /dev/null
@@ -1 +0,0 @@
-set:intersection(//*,//a:*)
diff --git a/tests/fuzz/seed/xpath/set_leading b/tests/fuzz/seed/xpath/set_leading
deleted file mode 100644
index 2b7209ff..00000000
--- a/tests/fuzz/seed/xpath/set_leading
+++ /dev/null
@@ -1 +0,0 @@
-set:leading(//*,/*/*[3])
diff --git a/tests/fuzz/seed/xpath/set_trailing b/tests/fuzz/seed/xpath/set_trailing
deleted file mode 100644
index fb00d07e..00000000
--- a/tests/fuzz/seed/xpath/set_trailing
+++ /dev/null
@@ -1 +0,0 @@
-set:trailing(//*,/*/*[2])
diff --git a/tests/fuzz/seed/xpath/str_align_center b/tests/fuzz/seed/xpath/str_align_center
deleted file mode 100644
index 4d906bf3..00000000
--- a/tests/fuzz/seed/xpath/str_align_center
+++ /dev/null
@@ -1 +0,0 @@
-str:align('déjà','--------','center')
diff --git a/tests/fuzz/seed/xpath/str_align_left b/tests/fuzz/seed/xpath/str_align_left
deleted file mode 100644
index 66a41084..00000000
--- a/tests/fuzz/seed/xpath/str_align_left
+++ /dev/null
@@ -1 +0,0 @@
-str:align('déjà','--------','left')
diff --git a/tests/fuzz/seed/xpath/str_align_right b/tests/fuzz/seed/xpath/str_align_right
deleted file mode 100644
index 03f20683..00000000
--- a/tests/fuzz/seed/xpath/str_align_right
+++ /dev/null
@@ -1 +0,0 @@
-str:align('déjà','--------','right')
diff --git a/tests/fuzz/seed/xpath/str_concat b/tests/fuzz/seed/xpath/str_concat
deleted file mode 100644
index 9b0bbce5..00000000
--- a/tests/fuzz/seed/xpath/str_concat
+++ /dev/null
@@ -1 +0,0 @@
-str:concat(str:split('ab,cd,ef',','))
diff --git a/tests/fuzz/seed/xpath/str_decode_uri b/tests/fuzz/seed/xpath/str_decode_uri
deleted file mode 100644
index f96b345c..00000000
--- a/tests/fuzz/seed/xpath/str_decode_uri
+++ /dev/null
@@ -1 +0,0 @@
-str:decode-uri('%41%00%2d')
diff --git a/tests/fuzz/seed/xpath/str_encode_uri_1 b/tests/fuzz/seed/xpath/str_encode_uri_1
deleted file mode 100644
index 97dbeae1..00000000
--- a/tests/fuzz/seed/xpath/str_encode_uri_1
+++ /dev/null
@@ -1 +0,0 @@
-str:encode-uri(';/?:@&=+$,[]',true())
diff --git a/tests/fuzz/seed/xpath/str_encode_uri_2 b/tests/fuzz/seed/xpath/str_encode_uri_2
deleted file mode 100644
index 09827ae5..00000000
--- a/tests/fuzz/seed/xpath/str_encode_uri_2
+++ /dev/null
@@ -1 +0,0 @@
-str:encode-uri('|<>',false())
diff --git a/tests/fuzz/seed/xpath/str_padding b/tests/fuzz/seed/xpath/str_padding
deleted file mode 100644
index 35736cc7..00000000
--- a/tests/fuzz/seed/xpath/str_padding
+++ /dev/null
@@ -1 +0,0 @@
-str:padding(81,' ')
diff --git a/tests/fuzz/seed/xpath/str_replace b/tests/fuzz/seed/xpath/str_replace
deleted file mode 100644
index 56056ae8..00000000
--- a/tests/fuzz/seed/xpath/str_replace
+++ /dev/null
@@ -1 +0,0 @@
-str:replace('abcdefgh',str:split('a,c,e,g',','),str:split('w,x,y,z',','))
diff --git a/tests/fuzz/seed/xpath/str_split b/tests/fuzz/seed/xpath/str_split
deleted file mode 100644
index f67c03c9..00000000
--- a/tests/fuzz/seed/xpath/str_split
+++ /dev/null
@@ -1 +0,0 @@
-str:split('a, sim, lis',', ')
diff --git a/tests/fuzz/seed/xpath/str_tokenize b/tests/fuzz/seed/xpath/str_tokenize
deleted file mode 100644
index fc74e187..00000000
--- a/tests/fuzz/seed/xpath/str_tokenize
+++ /dev/null
@@ -1 +0,0 @@
-str:tokenize('2016-01-01T12:00:00','-T:')
diff --git a/tests/fuzz/seed/xpath/xslt_current b/tests/fuzz/seed/xpath/xslt_current
deleted file mode 100644
index 79021cfc..00000000
--- a/tests/fuzz/seed/xpath/xslt_current
+++ /dev/null
@@ -1 +0,0 @@
-current()
diff --git a/tests/fuzz/seed/xpath/xslt_document b/tests/fuzz/seed/xpath/xslt_document
deleted file mode 100644
index c6027632..00000000
--- a/tests/fuzz/seed/xpath/xslt_document
+++ /dev/null
@@ -1 +0,0 @@
-document('')
diff --git a/tests/fuzz/seed/xpath/xslt_element_available b/tests/fuzz/seed/xpath/xslt_element_available
deleted file mode 100644
index 737c582c..00000000
--- a/tests/fuzz/seed/xpath/xslt_element_available
+++ /dev/null
@@ -1 +0,0 @@
-element-available('exsl:document')
diff --git a/tests/fuzz/seed/xpath/xslt_format_number b/tests/fuzz/seed/xpath/xslt_format_number
deleted file mode 100644
index f85ece94..00000000
--- a/tests/fuzz/seed/xpath/xslt_format_number
+++ /dev/null
@@ -1 +0,0 @@
-format-number(1.0,'##,##,00.00##')
diff --git a/tests/fuzz/seed/xpath/xslt_format_number_neg b/tests/fuzz/seed/xpath/xslt_format_number_neg
deleted file mode 100644
index 360c493f..00000000
--- a/tests/fuzz/seed/xpath/xslt_format_number_neg
+++ /dev/null
@@ -1 +0,0 @@
-format-number(1.0,'#.#;-0.0%')
diff --git a/tests/fuzz/seed/xpath/xslt_function_available b/tests/fuzz/seed/xpath/xslt_function_available
deleted file mode 100644
index 814530b7..00000000
--- a/tests/fuzz/seed/xpath/xslt_function_available
+++ /dev/null
@@ -1 +0,0 @@
-function-available('exsl:node-set')
diff --git a/tests/fuzz/seed/xpath/xslt_generate_id b/tests/fuzz/seed/xpath/xslt_generate_id
deleted file mode 100644
index 6221ee56..00000000
--- a/tests/fuzz/seed/xpath/xslt_generate_id
+++ /dev/null
@@ -1 +0,0 @@
-generate-id(.)
diff --git a/tests/fuzz/seed/xpath/xslt_system_property b/tests/fuzz/seed/xpath/xslt_system_property
deleted file mode 100644
index 643acb18..00000000
--- a/tests/fuzz/seed/xpath/xslt_system_property
+++ /dev/null
@@ -1 +0,0 @@
-system-property('xsl:version')
diff --git a/tests/fuzz/seed/xpath/xslt_unparsed_entity_uri b/tests/fuzz/seed/xpath/xslt_unparsed_entity_uri
deleted file mode 100644
index ba409c0c..00000000
--- a/tests/fuzz/seed/xpath/xslt_unparsed_entity_uri
+++ /dev/null
@@ -1 +0,0 @@
-unparsed-entity-uri('a')
diff --git a/tests/fuzz/seed/xslt/attr_set b/tests/fuzz/seed/xslt/attr_set
deleted file mode 100644
index 640c92f7..00000000
--- a/tests/fuzz/seed/xslt/attr_set
+++ /dev/null
@@ -1,9 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:attribute-set name="s"><x:attribute name="a:f" namespace="a">v</x:attribute></x:attribute-set>
-<x:attribute-set name="t" use-attribute-sets="s"><x:attribute name="g">w</x:attribute></x:attribute-set>
-<x:template match="a:*">
-<x:element name="e" use-attribute-sets="t"/>
-<a:e x:use-attribute-sets="t"/>
-<x:copy use-attribute-sets="t"></x:copy>
-</x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/cdata b/tests/fuzz/seed/xslt/cdata
deleted file mode 100644
index cb03937e..00000000
--- a/tests/fuzz/seed/xslt/cdata
+++ /dev/null
@@ -1,4 +0,0 @@
-<x:stylesheet version="1.0" xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b">
-<x:output cdata-section-elements="b a:c"/>
-<x:template match="*"><x:copy><x:apply-templates select="node()"/></x:copy></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/decimal_format b/tests/fuzz/seed/xslt/decimal_format
deleted file mode 100644
index 1a9332e2..00000000
--- a/tests/fuzz/seed/xslt/decimal_format
+++ /dev/null
@@ -1,15 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" version="1.0">
-<x:decimal-format name="f"
-decimal-separator="•" grouping-separator="`"
-infinity="∞" minus-sign="–" NaN="🀀"
-percent="⁄" per-mille="*"
-zero-digit="0" digit="÷"
-pattern-separator="|"/>
-<x:template match="*">
-<n><x:value-of select="format-number(123456789.123456,'_÷÷`÷`00•00÷÷_','f')"/></n>
-<n><x:value-of select="format-number(-1.5,'÷•÷*|–0•0⁄','f')"/></n>
-<n><x:value-of select="format-number(-1 div 0,'0','f')"/></n>
-<n><x:value-of select="format-number(0 div 0,'0','f')"/></n>
-</x:template>
-</x:stylesheet>
-
diff --git a/tests/fuzz/seed/xslt/element b/tests/fuzz/seed/xslt/element
deleted file mode 100644
index 7086695e..00000000
--- a/tests/fuzz/seed/xslt/element
+++ /dev/null
@@ -1,5 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:template match="*"><x:element name="e"><x:apply-templates select="node()|@*"/></x:element></x:template>
-<x:template match="@*"><x:attribute name="{local-name()}"></x:attribute></x:template>
-<x:template match="text()"><x:text></x:text></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/extension b/tests/fuzz/seed/xslt/extension
deleted file mode 100644
index 64e850f2..00000000
--- a/tests/fuzz/seed/xslt/extension
+++ /dev/null
@@ -1,7 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" xmlns:e1="e1" xmlns:e2="e2" xmlns:e3="e3" version="1.0" extension-element-prefixes="e1 e2 e3">
-<x:template match="*">
-<e3:e><x:fallback><f3/></x:fallback></e3:e>
-<x:foo><x:fallback><foo/></x:fallback></x:foo>
-<x:apply-templates select="*"/>
-</x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/html b/tests/fuzz/seed/xslt/html
deleted file mode 100644
index c171a2df..00000000
--- a/tests/fuzz/seed/xslt/html
+++ /dev/null
@@ -1,4 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:a="a" xmlns:b="b" exclude-result-prefixes="a b">
-<x:output method="html" version="4.0" encoding="iso-8859-1" indent="yes" media-type="t/h"/>
-<x:template match="*"><div><img/><x:apply-templates select="node()"/></div></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/key b/tests/fuzz/seed/xslt/key
deleted file mode 100644
index bda12f75..00000000
--- a/tests/fuzz/seed/xslt/key
+++ /dev/null
@@ -1,4 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:key name="k" match="*" use="."/>
-<x:template match="a:*"><x:copy-of select="key('k',.)"/></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/lre b/tests/fuzz/seed/xslt/lre
deleted file mode 100644
index 4930ad52..00000000
--- a/tests/fuzz/seed/xslt/lre
+++ /dev/null
@@ -1,3 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:template match="*"><a:e a="{1+1}"><a:f/></a:e></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/mode b/tests/fuzz/seed/xslt/mode
deleted file mode 100644
index 7d587a91..00000000
--- a/tests/fuzz/seed/xslt/mode
+++ /dev/null
@@ -1,4 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:template match="a:*"><x:apply-templates select="*" mode="m"/></x:template>
-<x:template match="*" mode="m"><r/></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/number b/tests/fuzz/seed/xslt/number
deleted file mode 100644
index ed38d63c..00000000
--- a/tests/fuzz/seed/xslt/number
+++ /dev/null
@@ -1,10 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" version="1.0">
-<x:template match="*">
-<x:number level="any" count="*" from="*" format="1.i.I.A.a"/>
-<x:number level="multiple" count="*" format="A.a.I.i.1"/>
-<x:number level="single" from="*"/>
-<x:number value="123456789" format="1" grouping-separator="’" grouping-size="3"/>
-<x:apply-templates select="*"/>
-</x:template>
-</x:stylesheet>
-
diff --git a/tests/fuzz/seed/xslt/output b/tests/fuzz/seed/xslt/output
deleted file mode 100644
index b1f0176b..00000000
--- a/tests/fuzz/seed/xslt/output
+++ /dev/null
@@ -1,4 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:a="a" xmlns:b="b" exclude-result-prefixes="a b">
-<x:output method="xml" version="1.0" encoding="iso-8859-1" omit-xml-declaration="yes" standalone="yes" doctype-public="p" doctype-system="s" cdata-section-elements="a" indent="yes" media-type="t/x"/>
-<x:template match="@*|node()"><x:copy><x:apply-templates select="@*|node()"/></x:copy></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/param b/tests/fuzz/seed/xslt/param
deleted file mode 100644
index f35c92a2..00000000
--- a/tests/fuzz/seed/xslt/param
+++ /dev/null
@@ -1,8 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:template match="*">
-<x:call-template name="n"><x:with-param name="p" select="."/></x:call-template>
-</x:template>
-<x:template name="n">
-<x:param name="p"/><x:value-of select="$p"/>
-</x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/sort b/tests/fuzz/seed/xslt/sort
deleted file mode 100644
index 2eebe979..00000000
--- a/tests/fuzz/seed/xslt/sort
+++ /dev/null
@@ -1,6 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:template match="*">
-<x:for-each select="*"><x:sort select="count(.)" data-type="number" order="ascending"/><x:value-of select="local-name()"/></x:for-each>
-<x:copy><x:apply-templates select="*"><x:sort select="." order="descending" lang="en"/></x:apply-templates></x:copy>
-</x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/strip_space b/tests/fuzz/seed/xslt/strip_space
deleted file mode 100644
index 563a327a..00000000
--- a/tests/fuzz/seed/xslt/strip_space
+++ /dev/null
@@ -1,6 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:strip-space elements="a b a:*"/>
-<x:preserve-space elements="a:e"/>
-<x:output indent="yes"/>
-<x:template match="*"><x:copy><x:apply-templates select="node()"/></x:copy></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/text b/tests/fuzz/seed/xslt/text
deleted file mode 100644
index 242c2691..00000000
--- a/tests/fuzz/seed/xslt/text
+++ /dev/null
@@ -1,4 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:output method="text" encoding="iso-8859-1" media-type="t/p"/>
-<x:template match="*"><x:copy><x:apply-templates select="node()"/></x:copy></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/variable b/tests/fuzz/seed/xslt/variable
deleted file mode 100644
index 5fa2be06..00000000
--- a/tests/fuzz/seed/xslt/variable
+++ /dev/null
@@ -1,4 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" xmlns:a="a" xmlns:b="b" version="1.0">
-<x:variable name="g" select="/*"/>
-<x:template match="a:*"><x:variable name="v" select="*"/><x:value-of select="$v"/></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/seed/xslt/xhtml b/tests/fuzz/seed/xslt/xhtml
deleted file mode 100644
index 3c521969..00000000
--- a/tests/fuzz/seed/xslt/xhtml
+++ /dev/null
@@ -1,4 +0,0 @@
-<x:stylesheet xmlns:x="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:a="a" xmlns:b="b" exclude-result-prefixes="a b">
-<x:output encoding="iso-8859-1" media-type="t/h" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>
-<x:template match="*"><div><img/><x:apply-templates select="node()"/></div></x:template>
-</x:stylesheet>
diff --git a/tests/fuzz/testTargets.c b/tests/fuzz/testTargets.c
index 3c5fdf8b..86026e78 100644
--- a/tests/fuzz/testTargets.c
+++ b/tests/fuzz/testTargets.c
@@ -10,23 +10,25 @@
#include <libxml/globals.h>
static int
-testXPath(int argc, char **argv) {
+testXPath(void) {
xmlXPathObjectPtr obj;
- const char expr[] = "count(//node())";
+ const char data[] =
+ "\0\0\0\0count(//node())\\\n"
+ "<d><e><f/></e></d>";
int ret = 0;
- if (xsltFuzzXPathInit(&argc, &argv, argv[1]) != 0) {
+ if (xsltFuzzXPathInit() != 0) {
xsltFuzzXPathCleanup();
return 1;
}
- obj = xsltFuzzXPath(expr, sizeof(expr) - 1);
+ obj = xsltFuzzXPath(data, sizeof(data) - 1);
if ((obj == NULL) || (obj->type != XPATH_NUMBER)) {
fprintf(stderr, "Expression doesn't evaluate to number\n");
ret = 1;
- } else if (obj->floatval != 39.0) {
+ } else if (obj->floatval != 3.0) {
fprintf(stderr, "Expression returned %f, expected %f\n",
- obj->floatval, 39.0);
+ obj->floatval, 3.0);
ret = 1;
}
@@ -37,9 +39,10 @@ testXPath(int argc, char **argv) {
}
static int
-testXslt(int argc, char **argv) {
+testXslt(void) {
xmlChar *result;
- const char styleBuf[] =
+ const char fuzzData[] =
+ "\0\0\0\0stylesheet.xsl\\\n"
"<xsl:stylesheet"
" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"
" version='1.0'"
@@ -50,21 +53,23 @@ testXslt(int argc, char **argv) {
"<xsl:template match='/'>\n"
" <r><xsl:value-of select='count(//node())'/></r>\n"
"</xsl:template>\n"
- "</xsl:stylesheet>\n";
+ "</xsl:stylesheet>\\\n"
+ "document.xml\\\n"
+ "<d><e><f/></e></d>";
int ret = 0;
- if (xsltFuzzXsltInit(&argc, &argv, argv[1]) != 0) {
+ if (xsltFuzzXsltInit() != 0) {
xsltFuzzXsltCleanup();
return 1;
}
- result = xsltFuzzXslt(styleBuf, sizeof(styleBuf) - 1);
+ result = xsltFuzzXslt(fuzzData, sizeof(fuzzData) - 1);
if (result == NULL) {
fprintf(stderr, "Result is NULL\n");
ret = 1;
- } else if (xmlStrcmp(result, BAD_CAST "<r>42</r>\n") != 0) {
+ } else if (xmlStrcmp(result, BAD_CAST "<r>3</r>\n") != 0) {
fprintf(stderr, "Stylesheet returned\n%sexpected \n%s\n",
- result, "<r>42</r>");
+ result, "<r>3</r>");
ret = 1;
}
@@ -74,12 +79,13 @@ testXslt(int argc, char **argv) {
return ret;
}
-int main(int argc, char **argv) {
+int
+main(void) {
int ret = 0;
- if (testXPath(argc, argv) != 0)
+ if (testXPath() != 0)
ret = 1;
- if (testXslt(argc, argv) != 0)
+ if (testXslt() != 0)
ret = 1;
return ret;
diff --git a/tests/fuzz/xpath.c b/tests/fuzz/xpath.c
index 475cb073..1f801795 100644
--- a/tests/fuzz/xpath.c
+++ b/tests/fuzz/xpath.c
@@ -7,8 +7,9 @@
#include "fuzz.h"
int
-LLVMFuzzerInitialize(int *argc_p, char ***argv_p) {
- return xsltFuzzXPathInit(argc_p, argv_p, NULL);
+LLVMFuzzerInitialize(int *argc_p ATTRIBUTE_UNUSED,
+ char ***argv_p ATTRIBUTE_UNUSED) {
+ return xsltFuzzXPathInit();
}
int
diff --git a/tests/fuzz/xpath.dict b/tests/fuzz/xpath.dict
index 6699fe8d..b20bdf7e 100644
--- a/tests/fuzz/xpath.dict
+++ b/tests/fuzz/xpath.dict
@@ -68,3 +68,18 @@ var_node_set="=$n"
utf8_2="\xC3\x84"
utf8_3="\xE2\x80\x9C"
utf8_4="\xF0\x9F\x98\x80"
+
+# XML
+
+elem_start_end="<a></a>"
+elem_ns_start_end="<a:a></a:a>"
+
+attr=" a='a'"
+
+ns_decl=" xmlns:a='a'"
+ns_default=" xmlns='a'"
+ns_prefix="a:"
+
+cdata_section="<![CDATA[ ]]>"
+comment="<!-- -->"
+pi="<?a?>"
diff --git a/tests/fuzz/xpath.xml b/tests/fuzz/xpath.xml
deleted file mode 100644
index 0ab51932..00000000
--- a/tests/fuzz/xpath.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?pi content?>
-<a xmlns:a="a">
- <b xmlns:b="b" a="1" id="b">
- <c b="2">Ärger</c>
- <b:d b="3">text</b:d>
- <!-- comment -->
- <a:b b="4">ß&#x1f600;</a:b>
- <b:c a="4"><![CDATA[text]]></b:c>
- </b>
- <?pi content?>
- <a:e xmlns:c="c" a="αβγ">
- <c:d b="2"/>
- <a:c>99</a:c>
- <e a="2">content</e>
- </a:e>
- <b/>
- <a:a/>
- <!-- comment -->
-</a>
diff --git a/tests/fuzz/xslt.c b/tests/fuzz/xslt.c
index 42ba7881..878ccd0b 100644
--- a/tests/fuzz/xslt.c
+++ b/tests/fuzz/xslt.c
@@ -8,8 +8,9 @@
#include <libxml/globals.h>
int
-LLVMFuzzerInitialize(int *argc_p, char ***argv_p) {
- return xsltFuzzXsltInit(argc_p, argv_p, NULL);
+LLVMFuzzerInitialize(int *argc_p ATTRIBUTE_UNUSED,
+ char ***argv_p ATTRIBUTE_UNUSED) {
+ return xsltFuzzXsltInit();
}
int
diff --git a/tests/fuzz/xslt.dict b/tests/fuzz/xslt.dict
index c7b53618..001605d8 100644
--- a/tests/fuzz/xslt.dict
+++ b/tests/fuzz/xslt.dict
@@ -81,3 +81,18 @@ expr_var="+$v"
utf8_2="\xC3\x84"
utf8_3="\xE2\x80\x9C"
utf8_4="\xF0\x9F\x98\x80"
+
+# XML
+
+elem_start_end="<a></a>"
+elem_ns_start_end="<a:a></a:a>"
+
+attr=" a='a'"
+
+ns_decl=" xmlns:a='a'"
+ns_default=" xmlns='a'"
+ns_prefix="a:"
+
+cdata_section="<![CDATA[ ]]>"
+comment="<!-- -->"
+pi="<?a?>"
diff --git a/tests/fuzz/xslt.xml b/tests/fuzz/xslt.xml
deleted file mode 100644
index b20eb192..00000000
--- a/tests/fuzz/xslt.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?pi content?>
-<a xmlns:a="a">
- <b xmlns:b="b" a="1" id="b">
- <c b="2">Ärger</c>
- <b:d b="3">text &amp; &lt;&gt;</b:d>
- <!-- comment -->
- <a:b b="4">
- <a:c>ß&#x1f600;</a:c>
- </a:b>
- <b:c a="4"><![CDATA[text]]></b:c>
- </b>
- <?pi content?>
- <a:e xmlns:c="c" a="αβγ">
- <c:d b="2"/>
- <a:c>99</a:c>
- <e a="2">content</e>
- </a:e>
- <b/>
- <a:a/>
- <!-- comment -->
-</a>