/src/solidity/test/tools/ossfuzz/solProtoFuzzer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | |
19 | | #include <test/tools/ossfuzz/protoToSol.h> |
20 | | #include <test/tools/ossfuzz/SolidityEvmoneInterface.h> |
21 | | #include <test/tools/ossfuzz/solProto.pb.h> |
22 | | |
23 | | #include <test/EVMHost.h> |
24 | | |
25 | | #include <evmone/evmone.h> |
26 | | #include <src/libfuzzer/libfuzzer_macro.h> |
27 | | |
28 | | #include <fstream> |
29 | | |
30 | | static evmc::VM evmone = evmc::VM{evmc_create_evmone()}; |
31 | | |
32 | | using namespace solidity::test::fuzzer; |
33 | | using namespace solidity::test::solprotofuzzer; |
34 | | using namespace solidity; |
35 | | using namespace solidity::frontend; |
36 | | using namespace solidity::test; |
37 | | using namespace solidity::util; |
38 | | |
39 | | DEFINE_PROTO_FUZZER(Program const& _input) |
40 | 273 | { |
41 | 273 | ProtoConverter converter; |
42 | 273 | std::string sol_source = converter.protoToSolidity(_input); |
43 | | |
44 | 273 | if (char const* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) |
45 | 0 | { |
46 | | // With libFuzzer binary run this to generate a YUL source file x.yul: |
47 | | // PROTO_FUZZER_DUMP_PATH=x.yul ./a.out proto-input |
48 | 0 | std::ofstream of(dump_path); |
49 | 0 | of.write(sol_source.data(), static_cast<std::streamsize>(sol_source.size())); |
50 | 0 | } |
51 | | |
52 | 273 | if (char const* dump_path = getenv("SOL_DEBUG_FILE")) |
53 | 0 | { |
54 | 0 | sol_source.clear(); |
55 | | // With libFuzzer binary run this to generate a YUL source file x.yul: |
56 | | // PROTO_FUZZER_LOAD_PATH=x.yul ./a.out proto-input |
57 | 0 | std::ifstream ifstr(dump_path); |
58 | 0 | sol_source = { |
59 | 0 | std::istreambuf_iterator<char>(ifstr), |
60 | 0 | std::istreambuf_iterator<char>() |
61 | 0 | }; |
62 | 0 | std::cout << sol_source << std::endl; |
63 | 0 | } |
64 | | |
65 | | // We target the default EVM which is the latest |
66 | 273 | langutil::EVMVersion version; |
67 | 273 | EVMHost hostContext(version, evmone); |
68 | 273 | std::string contractName = "C"; |
69 | 273 | std::string libraryName = converter.libraryTest() ? converter.libraryName() : ""; |
70 | 273 | std::string methodName = "test()"; |
71 | 273 | StringMap source({{"test.sol", sol_source}}); |
72 | 273 | CompilerInput cInput(version, source, contractName, OptimiserSettings::minimal(), {}); |
73 | 273 | EvmoneUtility evmoneUtil( |
74 | 273 | hostContext, |
75 | 273 | cInput, |
76 | 273 | contractName, |
77 | 273 | libraryName, |
78 | 273 | methodName |
79 | 273 | ); |
80 | 273 | auto minimalResult = evmoneUtil.compileDeployAndExecute(); |
81 | 273 | solAssert(minimalResult.status_code != EVMC_REVERT, "Sol proto fuzzer: Evmone reverted."); |
82 | 273 | if (minimalResult.status_code == EVMC_SUCCESS) |
83 | 273 | solAssert( |
84 | 273 | EvmoneUtility::zeroWord(minimalResult.output_data, minimalResult.output_size), |
85 | 273 | "Proto solc fuzzer: Output incorrect" |
86 | 273 | ); |
87 | 273 | } |