mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9459 from ethereum/fix-9458
Fuzzer: Count step by number of interpreted statements
This commit is contained in:
commit
47ab6e73a7
@ -99,7 +99,7 @@ string EwasmTranslationTest::interpret()
|
|||||||
{
|
{
|
||||||
InterpreterState state;
|
InterpreterState state;
|
||||||
state.maxTraceSize = 10000;
|
state.maxTraceSize = 10000;
|
||||||
state.maxSteps = 100000;
|
state.maxSteps = 1000000;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Interpreter::run(state, WasmDialect{}, *m_object->code);
|
Interpreter::run(state, WasmDialect{}, *m_object->code);
|
||||||
|
@ -97,15 +97,17 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
|||||||
EVMDialect::strictAssemblyForEVMObjects(version)
|
EVMDialect::strictAssemblyForEVMObjects(version)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (termReason == yulFuzzerUtil::TerminationReason::StepLimitReached)
|
if (
|
||||||
|
termReason == yulFuzzerUtil::TerminationReason::StepLimitReached ||
|
||||||
|
termReason == yulFuzzerUtil::TerminationReason::TraceLimitReached
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stack.optimize();
|
stack.optimize();
|
||||||
termReason = yulFuzzerUtil::interpret(
|
yulFuzzerUtil::interpret(
|
||||||
os2,
|
os2,
|
||||||
stack.parserResult()->code,
|
stack.parserResult()->code,
|
||||||
EVMDialect::strictAssemblyForEVMObjects(version),
|
EVMDialect::strictAssemblyForEVMObjects(version)
|
||||||
(yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 4)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
bool isTraceEq = (os1.str() == os2.str());
|
bool isTraceEq = (os1.str() == os2.str());
|
||||||
|
@ -145,6 +145,11 @@ void Interpreter::operator()(ForLoop const& _forLoop)
|
|||||||
}
|
}
|
||||||
while (evaluate(*_forLoop.condition) != 0)
|
while (evaluate(*_forLoop.condition) != 0)
|
||||||
{
|
{
|
||||||
|
// Increment step for each loop iteration for loops with
|
||||||
|
// an empty body and post blocks to prevent a deadlock.
|
||||||
|
if (_forLoop.body.statements.size() == 0 && _forLoop.post.statements.size() == 0)
|
||||||
|
incrementStep();
|
||||||
|
|
||||||
m_state.controlFlowState = ControlFlowState::Default;
|
m_state.controlFlowState = ControlFlowState::Default;
|
||||||
(*this)(_forLoop.body);
|
(*this)(_forLoop.body);
|
||||||
if (m_state.controlFlowState == ControlFlowState::Break || m_state.controlFlowState == ControlFlowState::Leave)
|
if (m_state.controlFlowState == ControlFlowState::Break || m_state.controlFlowState == ControlFlowState::Leave)
|
||||||
@ -176,12 +181,6 @@ void Interpreter::operator()(Leave const&)
|
|||||||
|
|
||||||
void Interpreter::operator()(Block const& _block)
|
void Interpreter::operator()(Block const& _block)
|
||||||
{
|
{
|
||||||
m_state.numSteps++;
|
|
||||||
if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps)
|
|
||||||
{
|
|
||||||
m_state.trace.emplace_back("Interpreter execution step limit reached.");
|
|
||||||
throw StepLimitReached();
|
|
||||||
}
|
|
||||||
enterScope(_block);
|
enterScope(_block);
|
||||||
// Register functions.
|
// Register functions.
|
||||||
for (auto const& statement: _block.statements)
|
for (auto const& statement: _block.statements)
|
||||||
@ -193,6 +192,7 @@ void Interpreter::operator()(Block const& _block)
|
|||||||
|
|
||||||
for (auto const& statement: _block.statements)
|
for (auto const& statement: _block.statements)
|
||||||
{
|
{
|
||||||
|
incrementStep();
|
||||||
visit(statement);
|
visit(statement);
|
||||||
if (m_state.controlFlowState != ControlFlowState::Default)
|
if (m_state.controlFlowState != ControlFlowState::Default)
|
||||||
break;
|
break;
|
||||||
@ -235,6 +235,16 @@ void Interpreter::leaveScope()
|
|||||||
yulAssert(m_scope, "");
|
yulAssert(m_scope, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Interpreter::incrementStep()
|
||||||
|
{
|
||||||
|
m_state.numSteps++;
|
||||||
|
if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps)
|
||||||
|
{
|
||||||
|
m_state.trace.emplace_back("Interpreter execution step limit reached.");
|
||||||
|
throw StepLimitReached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ExpressionEvaluator::operator()(Literal const& _literal)
|
void ExpressionEvaluator::operator()(Literal const& _literal)
|
||||||
{
|
{
|
||||||
static YulString const trueString("true");
|
static YulString const trueString("true");
|
||||||
|
@ -154,6 +154,10 @@ private:
|
|||||||
void enterScope(Block const& _block);
|
void enterScope(Block const& _block);
|
||||||
void leaveScope();
|
void leaveScope();
|
||||||
|
|
||||||
|
/// Increment interpreter step count, throwing exception if step limit
|
||||||
|
/// is reached.
|
||||||
|
void incrementStep();
|
||||||
|
|
||||||
Dialect const& m_dialect;
|
Dialect const& m_dialect;
|
||||||
InterpreterState& m_state;
|
InterpreterState& m_state;
|
||||||
/// Values of variables.
|
/// Values of variables.
|
||||||
|
Loading…
Reference in New Issue
Block a user