diff --git a/test/tools/ossfuzz/protoToYul.cpp b/test/tools/ossfuzz/protoToYul.cpp index fb800e3d5..b81931b78 100644 --- a/test/tools/ossfuzz/protoToYul.cpp +++ b/test/tools/ossfuzz/protoToYul.cpp @@ -35,9 +35,18 @@ using namespace solidity; string ProtoConverter::dictionaryToken(HexPrefix _p) { - unsigned indexVar = m_inputSize * m_inputSize + counter(); - std::string token = hexDictionary[indexVar % hexDictionary.size()]; - yulAssert(token.size() <= 64, "Proto Fuzzer: Dictionary token too large"); + std::string token; + // If dictionary constant is requested while converting + // for loop condition, then return zero so that we don't + // generate infinite for loops. + if (m_inForCond) + token = "0"; + else + { + unsigned indexVar = m_inputSize * m_inputSize + counter(); + token = hexDictionary[indexVar % hexDictionary.size()]; + yulAssert(token.size() <= 64, "Proto Fuzzer: Dictionary token too large"); + } return _p == HexPrefix::Add ? "0x" + token : token; } @@ -173,7 +182,13 @@ void ProtoConverter::visit(Expression const& _x) visit(_x.varref()); break; case Expression::kCons: - m_output << visit(_x.cons()); + // If literal expression describes for-loop condition + // then force it to zero, so we don't generate infinite + // for loops + if (m_inForCond) + m_output << "0"; + else + m_output << visit(_x.cons()); break; case Expression::kBinop: visit(_x.binop()); @@ -968,21 +983,26 @@ void ProtoConverter::visit(ForStmt const& _x) bool wasInForInit = m_inForInitScope; bool wasInBoundedForBodyScope = m_inBoundedForBodyScope; bool wasForInitScopeExtEnabled = m_forInitScopeExtEnabled; + bool wasInForCond = m_inForCond; m_inGenericForBodyScope = false; m_inForInitScope = true; m_inBoundedForBodyScope = false; m_forInitScopeExtEnabled = true; + m_inForCond = false; m_output << "for "; visit(_x.for_init()); m_inForInitScope = false; m_forInitScopeExtEnabled = wasForInitScopeExtEnabled; + m_inForCond = true; visit(_x.for_cond()); + m_inForCond = false; visit(_x.for_post()); m_inGenericForBodyScope = true; visit(_x.for_body()); m_inGenericForBodyScope = wasInGenericForBodyScope; m_inForInitScope = wasInForInit; m_inBoundedForBodyScope = wasInBoundedForBodyScope; + m_inForCond = wasInForCond; if (m_inFunctionDef) { yulAssert( diff --git a/test/tools/ossfuzz/protoToYul.h b/test/tools/ossfuzz/protoToYul.h index 8ca978f81..ff6fbac13 100644 --- a/test/tools/ossfuzz/protoToYul.h +++ b/test/tools/ossfuzz/protoToYul.h @@ -43,6 +43,7 @@ public: m_inGenericForBodyScope = false; m_inBoundedForBodyScope = false; m_inForInitScope = false; + m_inForCond = false; m_numNestedForLoops = 0; m_counter = 0; m_inputSize = 0; @@ -346,6 +347,9 @@ private: /// Predicate to keep track of for loop init scope. If true, variable /// or function declarations can not be created. bool m_inForInitScope; + /// Flag that is true while converting for loop condition, + /// false otherwise. + bool m_inForCond; /// Monotonically increasing counter unsigned m_counter; /// Size of protobuf input