aboutsummaryrefslogtreecommitdiffstats
path: root/test/fuzzer.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2017-02-16 23:59:19 +0800
committerchriseth <c@ethdev.com>2017-02-16 23:59:19 +0800
commitf93f9fa3a0dc1fada5688c0433a85cad1231a881 (patch)
tree7120b0a75b8976b909d16a18e6fa8c790bc2a87a /test/fuzzer.cpp
parentad751bd3e6f22fadc01d43610ec2e2e008c32f11 (diff)
downloaddexon-solidity-f93f9fa3a0dc1fada5688c0433a85cad1231a881.tar.gz
dexon-solidity-f93f9fa3a0dc1fada5688c0433a85cad1231a881.tar.zst
dexon-solidity-f93f9fa3a0dc1fada5688c0433a85cad1231a881.zip
Add executable for use with AFL.
Diffstat (limited to 'test/fuzzer.cpp')
-rw-r--r--test/fuzzer.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/test/fuzzer.cpp b/test/fuzzer.cpp
new file mode 100644
index 00000000..5e46662e
--- /dev/null
+++ b/test/fuzzer.cpp
@@ -0,0 +1,92 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * Executable for use with AFL <http://lcamtuf.coredump.cx/afl>.
+ * Reads a single source from stdin and signals a failure for internal errors.
+ */
+
+#include <json/json.h>
+
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+extern "C"
+{
+extern char const* compileJSON(char const* _input, bool _optimize);
+}
+
+string contains(string const& _haystack, vector<string> const& _needles)
+{
+ for (string const& needle: _needles)
+ if (_haystack.find(needle) != string::npos)
+ return needle;
+ return "";
+}
+
+int main()
+{
+ string input;
+ while (!cin.eof())
+ {
+ string s;
+ getline(cin, s);
+ input += s + '\n';
+ }
+
+ bool optimize = true;
+ string outputString(compileJSON(input.c_str(), optimize));
+ Json::Value outputJson;
+ if (!Json::Reader().parse(outputString, outputJson))
+ {
+ cout << "Compiler produced invalid JSON output." << endl;
+ return -1;
+ }
+ if (outputJson.isMember("errors"))
+ {
+ if (!outputJson["errors"].isArray())
+ {
+ cout << "Output JSON has \"errors\" but it is not an array." << endl;
+ return -1;
+ }
+ for (Json::Value const& error: outputJson["errors"])
+ {
+ string invalid = contains(error.asString(), vector<string>{
+ "Compiler error",
+ "Internal compiler error",
+ "Exception during compilation",
+ "Unknown exception during compilation",
+ "Unknown exception while generating contract data output",
+ "Unknown exception while generating formal method output",
+ "Unknown exception while generating source name output",
+ "Unknown error while generating JSON"
+ });
+ if (!invalid.empty())
+ {
+ cout << "Invalid error: \"" << invalid << "\"" << endl;
+ return -1;
+ }
+ }
+ }
+ else if (!outputJson.isMember("contracts"))
+ {
+ cout << "Output JSON has neither \"errors\" nor \"contracts\"." << endl;
+ return -1;
+ }
+ return 0;
+}