2018-02-06 09:57:16 +00:00
|
|
|
/*
|
|
|
|
This file is part of solidity.
|
|
|
|
|
|
|
|
solidity is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
solidity is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-07-17 14:54:12 +00:00
|
|
|
// SPDX-License-Identifier: GPL-3.0
|
2018-02-06 09:57:16 +00:00
|
|
|
#include <test/tools/ossfuzz/yulFuzzerCommon.h>
|
|
|
|
|
|
|
|
using namespace std;
|
2019-12-23 15:50:30 +00:00
|
|
|
using namespace solidity;
|
|
|
|
using namespace solidity::yul;
|
|
|
|
using namespace solidity::yul::test::yul_fuzzer;
|
2018-02-06 09:57:16 +00:00
|
|
|
|
2019-11-01 10:36:29 +00:00
|
|
|
yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret(
|
2019-04-05 12:06:19 +00:00
|
|
|
ostream& _os,
|
|
|
|
shared_ptr<yul::Block> _ast,
|
2019-04-30 13:02:52 +00:00
|
|
|
Dialect const& _dialect,
|
2021-04-12 07:34:58 +00:00
|
|
|
bool _outputStorageOnly,
|
2019-04-05 12:06:19 +00:00
|
|
|
size_t _maxSteps,
|
2020-07-23 09:58:10 +00:00
|
|
|
size_t _maxTraceSize,
|
|
|
|
size_t _maxExprNesting
|
2019-04-05 12:06:19 +00:00
|
|
|
)
|
2018-02-06 09:57:16 +00:00
|
|
|
{
|
|
|
|
InterpreterState state;
|
2019-04-05 12:06:19 +00:00
|
|
|
state.maxTraceSize = _maxTraceSize;
|
|
|
|
state.maxSteps = _maxSteps;
|
2020-07-23 09:58:10 +00:00
|
|
|
state.maxExprNesting = _maxExprNesting;
|
2019-10-10 08:07:08 +00:00
|
|
|
// Add 64 bytes of pseudo-randomly generated calldata so that
|
|
|
|
// calldata opcodes perform non trivial work.
|
|
|
|
state.calldata = {
|
|
|
|
0xe9, 0x96, 0x40, 0x7d, 0xa5, 0xda, 0xb0, 0x2d,
|
|
|
|
0x97, 0xf5, 0xc3, 0x44, 0xd7, 0x65, 0x0a, 0xd8,
|
|
|
|
0x2c, 0x14, 0x3a, 0xf3, 0xe7, 0x40, 0x0f, 0x1e,
|
|
|
|
0x67, 0xce, 0x90, 0x44, 0x2e, 0x92, 0xdb, 0x88,
|
|
|
|
0xb8, 0x43, 0x9c, 0x41, 0x42, 0x08, 0xf1, 0xd7,
|
|
|
|
0x65, 0xe9, 0x7f, 0xeb, 0x7b, 0xb9, 0x56, 0x9f,
|
|
|
|
0xc7, 0x60, 0x5f, 0x7c, 0xcd, 0xfb, 0x92, 0xcd,
|
|
|
|
0x8e, 0xf3, 0x9b, 0xe4, 0x4f, 0x6c, 0x14, 0xde
|
|
|
|
};
|
2019-11-01 10:36:29 +00:00
|
|
|
|
|
|
|
TerminationReason reason = TerminationReason::None;
|
|
|
|
try
|
|
|
|
{
|
2020-07-09 12:24:49 +00:00
|
|
|
Interpreter::run(state, _dialect, *_ast);
|
2019-11-01 10:36:29 +00:00
|
|
|
}
|
|
|
|
catch (StepLimitReached const&)
|
|
|
|
{
|
|
|
|
reason = TerminationReason::StepLimitReached;
|
|
|
|
}
|
|
|
|
catch (TraceLimitReached const&)
|
|
|
|
{
|
|
|
|
reason = TerminationReason::TraceLimitReached;
|
|
|
|
}
|
2020-07-23 09:58:10 +00:00
|
|
|
catch (ExpressionNestingLimitReached const&)
|
|
|
|
{
|
|
|
|
reason = TerminationReason::ExpresionNestingLimitReached;
|
|
|
|
}
|
2019-11-01 10:36:29 +00:00
|
|
|
catch (ExplicitlyTerminated const&)
|
|
|
|
{
|
|
|
|
reason = TerminationReason::ExplicitlyTerminated;
|
|
|
|
}
|
|
|
|
|
2021-04-12 07:34:58 +00:00
|
|
|
if (_outputStorageOnly)
|
|
|
|
state.dumpStorage(_os);
|
|
|
|
else
|
|
|
|
state.dumpTraceAndState(_os);
|
2019-11-01 10:36:29 +00:00
|
|
|
return reason;
|
2019-03-27 11:05:54 +00:00
|
|
|
}
|
2021-03-26 12:21:33 +00:00
|
|
|
|
|
|
|
bool yulFuzzerUtil::resourceLimitsExceeded(TerminationReason _reason)
|
|
|
|
{
|
|
|
|
return
|
|
|
|
_reason == yulFuzzerUtil::TerminationReason::StepLimitReached ||
|
|
|
|
_reason == yulFuzzerUtil::TerminationReason::TraceLimitReached ||
|
|
|
|
_reason == yulFuzzerUtil::TerminationReason::ExpresionNestingLimitReached;
|
|
|
|
}
|