Coverage Report

Created: 2022-08-24 06:55

/src/solidity/test/tools/ossfuzz/strictasm_diff_ossfuzz.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 <libyul/AsmAnalysisInfo.h>
20
#include <libyul/AsmAnalysis.h>
21
#include <libyul/Dialect.h>
22
#include <libyul/backends/evm/EVMDialect.h>
23
#include <libyul/YulStack.h>
24
25
#include <liblangutil/DebugInfoSelection.h>
26
#include <liblangutil/Exceptions.h>
27
#include <liblangutil/EVMVersion.h>
28
29
#include <libsolutil/CommonIO.h>
30
#include <libsolutil/CommonData.h>
31
#include <libsolutil/StringUtils.h>
32
33
#include <test/tools/ossfuzz/yulFuzzerCommon.h>
34
35
#include <string>
36
#include <memory>
37
#include <iostream>
38
39
using namespace std;
40
using namespace solidity;
41
using namespace solidity::yul;
42
using namespace solidity::util;
43
using namespace solidity::langutil;
44
using namespace solidity::yul::test::yul_fuzzer;
45
46
// Prototype as we can't use the FuzzerInterface.h header.
47
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size);
48
49
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
50
17.9k
{
51
17.9k
  if (_size > 600)
52
1
    return 0;
53
54
17.9k
  string input(reinterpret_cast<char const*>(_data), _size);
55
56
2.03M
  if (std::any_of(input.begin(), input.end(), [](char c) {
57
2.03M
    return ((static_cast<unsigned char>(c) > 127) || !(isPrint(c) || (c == '\n') || (c == '\t')));
58
2.03M
  }))
59
6
    return 0;
60
61
17.9k
  YulStringRepository::reset();
62
63
17.9k
  YulStack stack(
64
17.9k
    langutil::EVMVersion(),
65
17.9k
    YulStack::Language::StrictAssembly,
66
17.9k
    solidity::frontend::OptimiserSettings::full(),
67
17.9k
    DebugInfoSelection::All()
68
17.9k
  );
69
17.9k
  try
70
17.9k
  {
71
17.9k
    if (
72
17.9k
      !stack.parseAndAnalyze("source", input) ||
73
17.9k
      !stack.parserResult()->code ||
74
17.9k
      !stack.parserResult()->analysisInfo
75
17.9k
    )
76
3.93k
      return 0;
77
17.9k
  }
78
17.9k
  catch (Exception const&)
79
17.9k
  {
80
0
    return 0;
81
0
  }
82
83
13.9k
  ostringstream os1;
84
13.9k
  ostringstream os2;
85
  // Disable memory tracing to avoid false positive reports
86
  // such as unused write to memory e.g.,
87
  // { mstore(0, 1) }
88
  // that would be removed by the redundant store eliminator.
89
13.9k
  yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
90
13.9k
    os1,
91
13.9k
    stack.parserResult()->code,
92
13.9k
    EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()),
93
13.9k
    /*disableMemoryTracing=*/true
94
13.9k
  );
95
13.9k
  if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
96
1.30k
    return 0;
97
98
12.6k
  stack.optimize();
99
12.6k
  termReason = yulFuzzerUtil::interpret(
100
12.6k
    os2,
101
12.6k
    stack.parserResult()->code,
102
12.6k
    EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()),
103
12.6k
    /*disableMemoryTracing=*/true
104
12.6k
  );
105
106
12.6k
  if (yulFuzzerUtil::resourceLimitsExceeded(termReason))
107
224
    return 0;
108
109
12.4k
  bool isTraceEq = (os1.str() == os2.str());
110
12.4k
  yulAssert(isTraceEq, "Interpreted traces for optimized and unoptimized code differ.");
111
12.4k
  return 0;
112
12.4k
}