diff --git a/test/TestCaseReader.cpp b/test/TestCaseReader.cpp index 7b3611d82..d38e883ea 100644 --- a/test/TestCaseReader.cpp +++ b/test/TestCaseReader.cpp @@ -38,6 +38,13 @@ TestCaseReader::TestCaseReader(string const& _filename): m_unreadSettings = m_settings; } +TestCaseReader::TestCaseReader(istringstream const& _str) +{ + tie(m_sources, m_lineNumber) = parseSourcesAndSettingsWithLineNumber( + static_cast(const_cast(_str)) + ); +} + string const& TestCaseReader::source() const { if (m_sources.sources.size() != 1) diff --git a/test/TestCaseReader.h b/test/TestCaseReader.h index 720c26338..620565aee 100644 --- a/test/TestCaseReader.h +++ b/test/TestCaseReader.h @@ -42,6 +42,7 @@ class TestCaseReader public: TestCaseReader() = default; explicit TestCaseReader(std::string const& _filename); + explicit TestCaseReader(std::istringstream const& _testCode); SourceMap const& sources() const { return m_sources; } std::string const& source() const; diff --git a/test/tools/fuzzer_common.cpp b/test/tools/fuzzer_common.cpp index 437ab5d22..cb153e0e8 100644 --- a/test/tools/fuzzer_common.cpp +++ b/test/tools/fuzzer_common.cpp @@ -72,16 +72,16 @@ void FuzzerUtil::testCompilerJsonInterface(string const& _input, bool _optimize, runCompiler(jsonCompactPrint(config), _quiet); } -void FuzzerUtil::testCompiler(string const& _input, bool _optimize) +void FuzzerUtil::testCompiler(StringMap const& _input, bool _optimize, unsigned _rand) { frontend::CompilerStack compiler; - EVMVersion evmVersion = s_evmVersions[_input.size() % s_evmVersions.size()]; + EVMVersion evmVersion = s_evmVersions[_rand % s_evmVersions.size()]; frontend::OptimiserSettings optimiserSettings; if (_optimize) optimiserSettings = frontend::OptimiserSettings::standard(); else optimiserSettings = frontend::OptimiserSettings::minimal(); - compiler.setSources({{"", _input}}); + compiler.setSources(_input); compiler.setEVMVersion(evmVersion); compiler.setOptimiserSettings(optimiserSettings); try diff --git a/test/tools/fuzzer_common.h b/test/tools/fuzzer_common.h index c8749d9b1..cd30adc97 100644 --- a/test/tools/fuzzer_common.h +++ b/test/tools/fuzzer_common.h @@ -16,6 +16,9 @@ */ // SPDX-License-Identifier: GPL-3.0 +#include + +#include #include /** @@ -28,5 +31,9 @@ struct FuzzerUtil static void testCompilerJsonInterface(std::string const& _input, bool _optimize, bool _quiet); static void testConstantOptimizer(std::string const& _input, bool _quiet); static void testStandardCompiler(std::string const& _input, bool _quiet); - static void testCompiler(std::string const& _input, bool _optimize); + /// Compiles @param _input which is a map of input file name to source code + /// string with optimisation turned on if @param _optimize is true + /// (off otherwise) and a pseudo-random @param _rand that selects the EVM + /// version to be compiled for. + static void testCompiler(solidity::StringMap const& _input, bool _optimize, unsigned _rand); }; diff --git a/test/tools/ossfuzz/CMakeLists.txt b/test/tools/ossfuzz/CMakeLists.txt index 9ad7b9c80..a799bd736 100644 --- a/test/tools/ossfuzz/CMakeLists.txt +++ b/test/tools/ossfuzz/CMakeLists.txt @@ -23,11 +23,11 @@ if (OSSFUZZ) endif() if (OSSFUZZ) - add_executable(solc_opt_ossfuzz solc_opt_ossfuzz.cpp ../fuzzer_common.cpp) + add_executable(solc_opt_ossfuzz solc_opt_ossfuzz.cpp ../fuzzer_common.cpp ../../TestCaseReader.cpp) target_link_libraries(solc_opt_ossfuzz PRIVATE libsolc evmasm) set_target_properties(solc_opt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE}) - add_executable(solc_noopt_ossfuzz solc_noopt_ossfuzz.cpp ../fuzzer_common.cpp) + add_executable(solc_noopt_ossfuzz solc_noopt_ossfuzz.cpp ../fuzzer_common.cpp ../../TestCaseReader.cpp) target_link_libraries(solc_noopt_ossfuzz PRIVATE libsolc evmasm) set_target_properties(solc_noopt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE}) diff --git a/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp b/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp index e2f3a294f..8d615c0bd 100644 --- a/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp +++ b/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp @@ -18,6 +18,11 @@ #include +#include + +#include + +using namespace solidity::frontend::test; using namespace std; extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) @@ -25,7 +30,17 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) if (_size <= 600) { string input(reinterpret_cast(_data), _size); - FuzzerUtil::testCompiler(input, /*optimize=*/false); + map sourceCode; + try + { + TestCaseReader t = TestCaseReader(std::istringstream(input)); + sourceCode = t.sources().sources; + } + catch (runtime_error const&) + { + return 0; + } + FuzzerUtil::testCompiler(sourceCode, /*optimize=*/false, /*_rand=*/_size); } return 0; } diff --git a/test/tools/ossfuzz/solc_opt_ossfuzz.cpp b/test/tools/ossfuzz/solc_opt_ossfuzz.cpp index bff19407f..0d9c7f44e 100644 --- a/test/tools/ossfuzz/solc_opt_ossfuzz.cpp +++ b/test/tools/ossfuzz/solc_opt_ossfuzz.cpp @@ -18,14 +18,29 @@ #include +#include + +#include + +using namespace solidity::frontend::test; using namespace std; extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) { if (_size <= 600) { - string input(reinterpret_cast(_data), _size); - FuzzerUtil::testCompiler(input, /*optimize=*/true); + string input(reinterpret_cast(_data), _size); + map sourceCode; + try + { + TestCaseReader t = TestCaseReader(std::istringstream(input)); + sourceCode = t.sources().sources; + } + catch (runtime_error const&) + { + return 0; + } + FuzzerUtil::testCompiler(sourceCode, /*optimize=*/true, /*rand=*/_size); } return 0; }