yul proto fuzzer: Limit number of nested for loops

This commit is contained in:
Bhargava Shastry 2019-11-11 13:57:21 +01:00
parent b6b0a99afc
commit a3d84f0293
2 changed files with 25 additions and 0 deletions

View File

@ -856,23 +856,40 @@ void ProtoConverter::visit(StoreFunc const& _x)
void ProtoConverter::visit(ForStmt const& _x)
{
if (m_numNestedForLoops + 1 > s_maxNestedForLoops)
return;
if (m_inForBodyScope || m_inForPostScope || m_numNestedForLoops == 0)
m_numNestedForLoops++;
bool wasInForBody = m_inForBodyScope;
bool wasInForInit = m_inForInitScope;
bool wasInForPost = m_inForPostScope;
m_inForBodyScope = false;
m_inForPostScope = false;
m_inForInitScope = true;
m_output << "for ";
visit(_x.for_init());
m_inForInitScope = false;
visit(_x.for_cond());
m_inForPostScope = true;
visit(_x.for_post());
m_inForPostScope = false;
m_inForBodyScope = true;
visit(_x.for_body());
m_inForBodyScope = wasInForBody;
m_inForInitScope = wasInForInit;
m_inForPostScope = wasInForPost;
}
void ProtoConverter::visit(BoundedForStmt const& _x)
{
if (m_numNestedForLoops + 1 > s_maxNestedForLoops)
return;
if (m_inForBodyScope || m_inForPostScope || m_numNestedForLoops == 0)
m_numNestedForLoops++;
// Boilerplate for loop that limits the number of iterations to a maximum of 4.
std::string loopVarName("i_" + std::to_string(m_numNestedForLoops++));
m_output << "for { let " << loopVarName << " := 0 } "
@ -881,12 +898,15 @@ void ProtoConverter::visit(BoundedForStmt const& _x)
// Store previous for body scope
bool wasInForBody = m_inForBodyScope;
bool wasInForInit = m_inForInitScope;
bool wasInForPost = m_inForPostScope;
m_inForBodyScope = true;
m_inForInitScope = false;
m_inForPostScope = false;
visit(_x.for_body());
// Restore previous for body scope and init
m_inForBodyScope = wasInForBody;
m_inForInitScope = wasInForInit;
m_inForPostScope = wasInForPost;
}
void ProtoConverter::visit(CaseStmt const& _x)

View File

@ -46,6 +46,7 @@ public:
m_variables = std::vector<std::vector<std::string>>{};
m_inForBodyScope = false;
m_inForInitScope = false;
m_inForPostScope = false;
m_numNestedForLoops = 0;
m_numFunctionCalls = 0;
m_counter = 0;
@ -337,6 +338,8 @@ private:
static unsigned constexpr s_maxFunctionCalls = 3;
/// Lower bound for function statement count to be considered non-trivial
static unsigned constexpr s_minStatements = 5;
/// Upper bound for number of nested for loops
static unsigned constexpr s_maxNestedForLoops = 3;
/// Hard-coded identifier for a Yul object's data block
static auto constexpr s_dataIdentifier = "datablock";
/// Predicate to keep track of for body scope. If true, break/continue
@ -349,6 +352,8 @@ private:
/// Predicate to keep track of for loop init scope. If true, variable
/// or function declarations can not be created.
bool m_inForInitScope;
/// Predicate to keep track of for loop post scope.
bool m_inForPostScope;
/// Monotonically increasing counter
unsigned m_counter;
/// Size of protobuf input