diff options
author | chriseth <chris@ethereum.org> | 2017-04-28 00:10:28 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-28 00:10:28 +0800 |
commit | a8cf9f8178f276b6cc626accb20a52cdd60bf104 (patch) | |
tree | b51dec4c8ba06cad850759cc1cee16292e10eac2 | |
parent | 2c8b77006255b15743efd0b54964227bccc07c57 (diff) | |
parent | 28902f9f425eee83fe3b5699cc132f752e44108a (diff) | |
download | dexon-solidity-a8cf9f8178f276b6cc626accb20a52cdd60bf104.tar dexon-solidity-a8cf9f8178f276b6cc626accb20a52cdd60bf104.tar.gz dexon-solidity-a8cf9f8178f276b6cc626accb20a52cdd60bf104.tar.bz2 dexon-solidity-a8cf9f8178f276b6cc626accb20a52cdd60bf104.tar.lz dexon-solidity-a8cf9f8178f276b6cc626accb20a52cdd60bf104.tar.xz dexon-solidity-a8cf9f8178f276b6cc626accb20a52cdd60bf104.tar.zst dexon-solidity-a8cf9f8178f276b6cc626accb20a52cdd60bf104.zip |
Merge pull request #2183 from ethereum/fuzzer-jsonio
Add --standard-json option to solfuzzer
-rw-r--r-- | test/CMakeLists.txt | 2 | ||||
-rwxr-xr-x | test/cmdlineTests.sh | 2 | ||||
-rw-r--r-- | test/fuzzer.cpp | 137 |
3 files changed, 137 insertions, 4 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4d56ec9d..01a9a188 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -21,4 +21,4 @@ include_directories(BEFORE ..) target_link_libraries(${EXECUTABLE} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) add_executable(solfuzzer fuzzer.cpp) -target_link_libraries(solfuzzer soljson) +target_link_libraries(solfuzzer soljson ${Boost_PROGRAM_OPTIONS_LIBRARIES}) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index caf09a91..6dc3f77f 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -79,7 +79,7 @@ TMPDIR=$(mktemp -d) "$REPO_ROOT"/scripts/isolate_tests.py "$REPO_ROOT"/test/ for f in *.sol do - "$REPO_ROOT"/build/test/solfuzzer < "$f" + "$REPO_ROOT"/build/test/solfuzzer --quiet < "$f" done ) rm -rf "$TMPDIR" diff --git a/test/fuzzer.cpp b/test/fuzzer.cpp index 410313c5..afa50671 100644 --- a/test/fuzzer.cpp +++ b/test/fuzzer.cpp @@ -16,21 +16,32 @@ */ /** * Executable for use with AFL <http://lcamtuf.coredump.cx/afl>. - * Reads a single source from stdin and signals a failure for internal errors. */ +#include <libevmasm/Assembly.h> +#include <libevmasm/ConstantOptimiser.h> + #include <json/json.h> +#include <boost/program_options.hpp> + #include <string> #include <iostream> using namespace std; +using namespace dev; +using namespace dev::eth; +namespace po = boost::program_options; extern "C" { extern char const* compileJSON(char const* _input, bool _optimize); +typedef void (*CStyleReadFileCallback)(char const* _path, char** o_contents, char** o_error); +extern char const* compileStandard(char const* _input, CStyleReadFileCallback _readCallback); } +bool quiet = false; + string contains(string const& _haystack, vector<string> const& _needles) { for (string const& needle: _needles) @@ -39,7 +50,42 @@ string contains(string const& _haystack, vector<string> const& _needles) return ""; } -int main() +void testConstantOptimizer() +{ + if (!quiet) + cout << "Testing constant optimizer" << endl; + vector<u256> numbers; + while (!cin.eof()) + { + h256 data; + cin.read(reinterpret_cast<char*>(data.data()), 32); + numbers.push_back(u256(data)); + } + if (!quiet) + cout << "Got " << numbers.size() << " inputs:" << endl; + + Assembly assembly; + for (u256 const& n: numbers) + { + if (!quiet) + cout << n << endl; + assembly.append(n); + } + for (bool isCreation: {false, true}) + { + for (unsigned runs: {1, 2, 3, 20, 40, 100, 200, 400, 1000}) + { + ConstantOptimisationMethod::optimiseConstants( + isCreation, + runs, + assembly, + const_cast<AssemblyItems&>(assembly.items()) + ); + } + } +} + +string readInput() { string input; while (!cin.eof()) @@ -48,6 +94,41 @@ int main() getline(cin, s); input += s + '\n'; } + return input; +} + +void testStandardCompiler() +{ + if (!quiet) + cout << "Testing compiler via JSON interface." << endl; + string input = readInput(); + string outputString(compileStandard(input.c_str(), NULL)); + Json::Value output; + if (!Json::Reader().parse(outputString, output)) + { + cout << "Compiler produced invalid JSON output." << endl; + abort(); + } + if (output.isMember("errors")) + for (auto const& error: output["errors"]) + { + string invalid = contains(error["type"].asString(), vector<string>{ + "Exception", + "InternalCompilerError" + }); + if (!invalid.empty()) + { + cout << "Invalid error: \"" << error["type"].asString() << "\"" << endl; + abort(); + } + } +} + +void testCompiler() +{ + if (!quiet) + cout << "Testing compiler." << endl; + string input = readInput(); bool optimize = true; string outputString(compileJSON(input.c_str(), optimize)); @@ -87,5 +168,57 @@ int main() cout << "Output JSON has neither \"errors\" nor \"contracts\"." << endl; abort(); } +} + +int main(int argc, char** argv) +{ + po::options_description options( + R"(solfuzzer, fuzz-testing binary for use with AFL. +Usage: solfuzzer [Options] < input +Reads a single source from stdin, compiles it and signals a failure for internal errors. + +Allowed options)", + po::options_description::m_default_line_length, + po::options_description::m_default_line_length - 23); + options.add_options() + ("help", "Show this help screen.") + ("quiet", "Only output errors.") + ( + "standard-json", + "Test via the standard-json interface, i.e. " + "input is expected to be JSON-encoded instead of " + "plain source file." + ) + ( + "const-opt", + "Run the constant optimizer instead of compiling. " + "Expects a binary string of up to 32 bytes on stdin." + ); + + po::variables_map arguments; + try + { + po::command_line_parser cmdLineParser(argc, argv); + cmdLineParser.options(options); + po::store(cmdLineParser.run(), arguments); + } + catch (po::error const& _exception) + { + cerr << _exception.what() << endl; + return false; + } + + if (arguments.count("quiet")) + quiet = true; + + if (arguments.count("help")) + cout << options; + else if (arguments.count("const-opt")) + testConstantOptimizer(); + else if (arguments.count("standard-json")) + testStandardCompiler(); + else + testCompiler(); + return 0; } |