Coverage Report

Created: 2025-09-04 07:34

/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
}