summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-02-11 13:51:39 -0800
committerGitHub <noreply@github.com>2017-02-11 13:51:39 -0800
commit03e4b8de929328eb5cbb031ff535c50396d43bb9 (patch)
tree0552947207245d263abffb91e1c6b1d92b86e653
parent02c599f52b8817916405b4263da3616a55f77632 (diff)
parentec984370fb525d0cbc20b009f69c9c5eaec022a7 (diff)
Merge pull request #132 from zeux/fuzz
Improve fuzzing support
-rw-r--r--Makefile11
-rw-r--r--tests/data_fuzz_xpath/basic.xpath1
-rw-r--r--tests/data_fuzz_xpath/functions.xpath1
-rw-r--r--tests/data_fuzz_xpath/math.xpath1
-rw-r--r--tests/data_fuzz_xpath/path.xpath1
-rw-r--r--tests/data_fuzz_xpath/predicate.xpath1
-rw-r--r--tests/fuzz_parse.cpp18
-rw-r--r--tests/fuzz_parse.dict72
-rwxr-xr-xtests/fuzz_setup.sh13
-rw-r--r--tests/fuzz_xpath.cpp26
-rw-r--r--tests/fuzz_xpath.dict72
11 files changed, 203 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index f9b26d6..500675c 100644
--- a/Makefile
+++ b/Makefile
@@ -68,10 +68,9 @@ test: $(EXECUTABLE)
./$(EXECUTABLE)
endif
-fuzz:
- @mkdir -p $(BUILD)
- $(AFL)/afl-clang++ tests/fuzz_parse.cpp tests/allocator.cpp src/pugixml.cpp $(CXXFLAGS) -o $(BUILD)/fuzz_parse
- $(AFL)/afl-fuzz -i tests/data_fuzz_parse -o $(BUILD)/fuzz_parse_out -x $(AFL)/testcases/_extras/xml/ -- $(BUILD)/fuzz_parse @@
+fuzz_%: $(BUILD)/fuzz_%
+ @mkdir -p build/$@
+ $< build/$@ tests/data_$* -max_len=1024 -dict=tests/fuzz_$*.dict
clean:
rm -rf $(BUILD)
@@ -87,6 +86,10 @@ build/pugixml-%: .FORCE | $(RELEASE)
$(EXECUTABLE): $(OBJECTS)
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
+$(BUILD)/fuzz_%: tests/fuzz_%.cpp src/pugixml.cpp
+ @mkdir -p $(BUILD)
+ clang++ $(CXXFLAGS) -fsanitize=address -fsanitize-coverage=trace-pc-guard $^ libFuzzer.a -o $@
+
$(BUILD)/%.o: %
@mkdir -p $(dir $@)
$(CXX) $< $(CXXFLAGS) -c -MMD -MP -o $@
diff --git a/tests/data_fuzz_xpath/basic.xpath b/tests/data_fuzz_xpath/basic.xpath
new file mode 100644
index 0000000..ccbaf23
--- /dev/null
+++ b/tests/data_fuzz_xpath/basic.xpath
@@ -0,0 +1 @@
+a/b/c \ No newline at end of file
diff --git a/tests/data_fuzz_xpath/functions.xpath b/tests/data_fuzz_xpath/functions.xpath
new file mode 100644
index 0000000..ec24b4f
--- /dev/null
+++ b/tests/data_fuzz_xpath/functions.xpath
@@ -0,0 +1 @@
+sum(nodes) + round(concat(//a[translate(@id, 'abc', '012')]))
diff --git a/tests/data_fuzz_xpath/math.xpath b/tests/data_fuzz_xpath/math.xpath
new file mode 100644
index 0000000..7f6e968
--- /dev/null
+++ b/tests/data_fuzz_xpath/math.xpath
@@ -0,0 +1 @@
+1+2*3 div 4 mod 5-6 \ No newline at end of file
diff --git a/tests/data_fuzz_xpath/path.xpath b/tests/data_fuzz_xpath/path.xpath
new file mode 100644
index 0000000..82cace9
--- /dev/null
+++ b/tests/data_fuzz_xpath/path.xpath
@@ -0,0 +1 @@
+@*/ancestor::*/near-north/*[4]/@*/preceding::text() \ No newline at end of file
diff --git a/tests/data_fuzz_xpath/predicate.xpath b/tests/data_fuzz_xpath/predicate.xpath
new file mode 100644
index 0000000..7161d55
--- /dev/null
+++ b/tests/data_fuzz_xpath/predicate.xpath
@@ -0,0 +1 @@
+library/nodes[@id=12]/element[@type='translate'][1] \ No newline at end of file
diff --git a/tests/fuzz_parse.cpp b/tests/fuzz_parse.cpp
index e758196..94c610a 100644
--- a/tests/fuzz_parse.cpp
+++ b/tests/fuzz_parse.cpp
@@ -1,16 +1,14 @@
#include "../src/pugixml.hpp"
-#include "allocator.hpp"
-int main(int argc, const char** argv)
-{
- pugi::set_memory_management_functions(memory_allocate, memory_deallocate);
+#include <stdint.h>
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
+{
pugi::xml_document doc;
- for (int i = 1; i < argc; ++i)
- {
- doc.load_file(argv[i]);
- doc.load_file(argv[i], pugi::parse_minimal);
- doc.load_file(argv[i], pugi::parse_full);
- }
+ doc.load_buffer(Data, Size);
+ doc.load_buffer(Data, Size, pugi::parse_minimal);
+ doc.load_buffer(Data, Size, pugi::parse_full);
+
+ return 0;
}
diff --git a/tests/fuzz_parse.dict b/tests/fuzz_parse.dict
new file mode 100644
index 0000000..b1a0067
--- /dev/null
+++ b/tests/fuzz_parse.dict
@@ -0,0 +1,72 @@
+#
+# AFL dictionary for XML
+# ----------------------
+#
+# Several basic syntax elements and attributes, modeled on libxml2.
+#
+# Created by Michal Zalewski <lcamtuf@google.com>
+#
+
+attr_encoding=" encoding=\"1\""
+attr_generic=" a=\"1\""
+attr_href=" href=\"1\""
+attr_standalone=" standalone=\"no\""
+attr_version=" version=\"1\""
+attr_xml_base=" xml:base=\"1\""
+attr_xml_id=" xml:id=\"1\""
+attr_xml_lang=" xml:lang=\"1\""
+attr_xml_space=" xml:space=\"1\""
+attr_xmlns=" xmlns=\"1\""
+
+entity_builtin="&lt;"
+entity_decimal="&#1;"
+entity_external="&a;"
+entity_hex="&#x1;"
+
+string_any="ANY"
+string_brackets="[]"
+string_cdata="CDATA"
+string_col_fallback=":fallback"
+string_col_generic=":a"
+string_col_include=":include"
+string_dashes="--"
+string_empty="EMPTY"
+string_empty_dblquotes="\"\""
+string_empty_quotes="''"
+string_entities="ENTITIES"
+string_entity="ENTITY"
+string_fixed="#FIXED"
+string_id="ID"
+string_idref="IDREF"
+string_idrefs="IDREFS"
+string_implied="#IMPLIED"
+string_nmtoken="NMTOKEN"
+string_nmtokens="NMTOKENS"
+string_notation="NOTATION"
+string_parentheses="()"
+string_pcdata="#PCDATA"
+string_percent="%a"
+string_public="PUBLIC"
+string_required="#REQUIRED"
+string_schema=":schema"
+string_system="SYSTEM"
+string_ucs4="UCS-4"
+string_utf16="UTF-16"
+string_utf8="UTF-8"
+string_xmlns="xmlns:"
+
+tag_attlist="<!ATTLIST"
+tag_cdata="<![CDATA["
+tag_close="</a>"
+tag_doctype="<!DOCTYPE"
+tag_element="<!ELEMENT"
+tag_entity="<!ENTITY"
+tag_ignore="<![IGNORE["
+tag_include="<![INCLUDE["
+tag_notation="<!NOTATION"
+tag_open="<a>"
+tag_open_close="<a />"
+tag_open_exclamation="<!"
+tag_open_q="<?"
+tag_sq2_close="]]>"
+tag_xml_q="<?xml?>"
diff --git a/tests/fuzz_setup.sh b/tests/fuzz_setup.sh
new file mode 100755
index 0000000..05a40cb
--- /dev/null
+++ b/tests/fuzz_setup.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+sudo apt-get --yes install subversion screen gcc g++ cmake ninja-build golang autoconf libtool apache2 python-dev pkg-config zlib1g-dev libgcrypt11-dev
+
+cd clang
+git clone https://chromium.googlesource.com/chromium/src/tools/clang
+cd ..
+clang/clang/scripts/update.py
+sudo cp -rf third_party/llvm-build/Release+Asserts/lib/* /usr/local/lib/
+sudo cp -rf third_party/llvm-build/Release+Asserts/bin/* /usr/local/bin
+
+svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
+Fuzzer/build.sh
diff --git a/tests/fuzz_xpath.cpp b/tests/fuzz_xpath.cpp
new file mode 100644
index 0000000..c7ff4cd
--- /dev/null
+++ b/tests/fuzz_xpath.cpp
@@ -0,0 +1,26 @@
+#include "../src/pugixml.hpp"
+
+#include <stdint.h>
+#include <string.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
+{
+ char* text = new char[Size + 1];
+ memcpy(text, Data, Size);
+ text[Size] = 0;
+
+#ifdef PUGIXML_NO_EXCEPTIONS
+ pugi::xpath_query q(text);
+#else
+ try
+ {
+ pugi::xpath_query q(text);
+ }
+ catch (pugi::xpath_exception&)
+ {
+ }
+#endif
+
+ delete[] text;
+ return 0;
+}
diff --git a/tests/fuzz_xpath.dict b/tests/fuzz_xpath.dict
new file mode 100644
index 0000000..c469f6e
--- /dev/null
+++ b/tests/fuzz_xpath.dict
@@ -0,0 +1,72 @@
+"boolean"
+"count"
+"contains"
+"concat"
+"ceiling"
+"false"
+"floor"
+"id"
+"last"
+"lang"
+"local-name"
+"name"
+"namespace-uri"
+"normalize-space"
+"not"
+"number"
+"position"
+"round"
+"string"
+"string-length"
+"starts-with"
+"substring-before"
+"substring-after"
+"substring"
+"sum"
+"translate"
+"true"
+"ancestor"
+"ancestor-or-self"
+"attribute"
+"child"
+"descendant"
+"descendant-or-self"
+"following"
+"following-sibling"
+"namespace"
+"parent"
+"preceding"
+"preceding-sibling"
+"self"
+"comment"
+"node"
+"processing-instruction"
+"text"
+"or"
+"and"
+"div"
+"mod"
+">"
+">="
+"<"
+"<="
+"!"
+"!="
+"="
+"+"
+"-"
+"*"
+"|"
+"$"
+"("
+")"
+"["
+"]"
+","
+"//"
+"/"
+".."
+"."
+"@"
+"::"
+":"