/src/solidity/test/tools/ossfuzz/AbiV2IsabelleFuzzer.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/SolidityEvmoneInterface.h> |
20 | | |
21 | | #include <test/tools/ossfuzz/protoToAbiV2.h> |
22 | | |
23 | | #include <src/libfuzzer/libfuzzer_macro.h> |
24 | | #include <abicoder.hpp> |
25 | | #include <fstream> |
26 | | |
27 | | using namespace solidity::frontend; |
28 | | using namespace solidity::test::fuzzer; |
29 | | using namespace solidity::test::abiv2fuzzer; |
30 | | using namespace solidity::test; |
31 | | using namespace solidity::util; |
32 | | using namespace solidity; |
33 | | |
34 | | static constexpr size_t abiCoderHeapSize = 1024 * 512; |
35 | | static evmc::VM evmone = evmc::VM{evmc_create_evmone()}; |
36 | | |
37 | | DEFINE_PROTO_FUZZER(Contract const& _contract) |
38 | 143 | { |
39 | 143 | ProtoConverter converter(_contract.seed()); |
40 | 143 | std::string contractSource = converter.contractToString(_contract); |
41 | | |
42 | 143 | if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) |
43 | 0 | { |
44 | | // With libFuzzer binary run this to generate the solidity source file x.sol from a proto input: |
45 | | // PROTO_FUZZER_DUMP_PATH=x.sol ./a.out proto-input |
46 | 0 | std::ofstream of(dump_path); |
47 | 0 | of << contractSource; |
48 | 0 | } |
49 | | |
50 | 143 | std::string typeString = converter.isabelleTypeString(); |
51 | 143 | std::string valueString = converter.isabelleValueString(); |
52 | 143 | abicoder::ABICoder coder(abiCoderHeapSize); |
53 | 143 | if (!typeString.empty() && converter.coderFunction()) |
54 | 127 | { |
55 | 127 | auto [encodeStatus, encodedData] = coder.encode(typeString, valueString); |
56 | 127 | solAssert(encodeStatus, "Isabelle abicoder fuzzer: Encoding failed"); |
57 | | |
58 | | // We target the default EVM which is the latest |
59 | 127 | langutil::EVMVersion version; |
60 | 127 | EVMHost hostContext(version, evmone); |
61 | 127 | std::string contractName = "C"; |
62 | 127 | StringMap source({{"test.sol", contractSource}}); |
63 | 127 | CompilerInput cInput(version, source, contractName, OptimiserSettings::minimal(), {}); |
64 | 127 | EvmoneUtility evmoneUtil( |
65 | 127 | hostContext, |
66 | 127 | cInput, |
67 | 127 | contractName, |
68 | 127 | {}, |
69 | 127 | {} |
70 | 127 | ); |
71 | 127 | auto result = evmoneUtil.compileDeployAndExecute(encodedData); |
72 | 127 | solAssert(result.status_code != EVMC_REVERT, "Proto ABIv2 fuzzer: EVM One reverted."); |
73 | 127 | if (result.status_code == EVMC_SUCCESS) |
74 | 127 | solAssert( |
75 | 127 | EvmoneUtility::zeroWord(result.output_data, result.output_size), |
76 | 127 | "Proto ABIv2 fuzzer: ABIv2 coding failure found." |
77 | 127 | ); |
78 | 127 | } |
79 | 143 | } |