mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	yul proto fuzzer: Catch exception early and propagate termination reason to harness
This commit is contained in:
		
							parent
							
								
									1bd2b202e9
								
							
						
					
					
						commit
						e4ba1c02e8
					
				| @ -78,35 +78,21 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size) | ||||
| 
 | ||||
| 	ostringstream os1; | ||||
| 	ostringstream os2; | ||||
| 	try | ||||
| 	{ | ||||
| 		yulFuzzerUtil::interpret( | ||||
| 			os1, | ||||
| 			stack.parserResult()->code, | ||||
| 			EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()) | ||||
| 		); | ||||
| 	} | ||||
| 	catch (yul::test::StepLimitReached const&) | ||||
| 	{ | ||||
| 	yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( | ||||
| 		os1, | ||||
| 		stack.parserResult()->code, | ||||
| 		EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()) | ||||
| 	); | ||||
| 	if (termReason == yulFuzzerUtil::TerminationReason::StepLimitReached) | ||||
| 		return 0; | ||||
| 	} | ||||
| 	catch (yul::test::InterpreterTerminatedGeneric const&) | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	stack.optimize(); | ||||
| 	try | ||||
| 	{ | ||||
| 		yulFuzzerUtil::interpret( | ||||
| 			os2, | ||||
| 			stack.parserResult()->code, | ||||
| 			EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), | ||||
| 			(yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 1.5) | ||||
| 		); | ||||
| 	} | ||||
| 	catch (yul::test::InterpreterTerminatedGeneric const&) | ||||
| 	{ | ||||
| 	} | ||||
| 	termReason = yulFuzzerUtil::interpret( | ||||
| 		os2, | ||||
| 		stack.parserResult()->code, | ||||
| 		EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), | ||||
| 		(yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 1.5) | ||||
| 	); | ||||
| 
 | ||||
| 	bool isTraceEq = (os1.str() == os2.str()); | ||||
| 	yulAssert(isTraceEq, "Interpreted traces for optimized and unoptimized code differ."); | ||||
|  | ||||
| @ -20,7 +20,7 @@ using namespace std; | ||||
| using namespace yul; | ||||
| using namespace yul::test::yul_fuzzer; | ||||
| 
 | ||||
| void yulFuzzerUtil::interpret( | ||||
| yulFuzzerUtil::TerminationReason yulFuzzerUtil::interpret( | ||||
| 	ostream& _os, | ||||
| 	shared_ptr<yul::Block> _ast, | ||||
| 	Dialect const& _dialect, | ||||
| @ -44,6 +44,25 @@ void yulFuzzerUtil::interpret( | ||||
| 		0x8e, 0xf3, 0x9b, 0xe4, 0x4f, 0x6c, 0x14, 0xde | ||||
| 	}; | ||||
| 	Interpreter interpreter(state, _dialect); | ||||
| 	interpreter(*_ast); | ||||
| 
 | ||||
| 	TerminationReason reason = TerminationReason::None; | ||||
| 	try | ||||
| 	{ | ||||
| 		interpreter(*_ast); | ||||
| 	} | ||||
| 	catch (StepLimitReached const&) | ||||
| 	{ | ||||
| 		reason = TerminationReason::StepLimitReached; | ||||
| 	} | ||||
| 	catch (TraceLimitReached const&) | ||||
| 	{ | ||||
| 		reason = TerminationReason::TraceLimitReached; | ||||
| 	} | ||||
| 	catch (ExplicitlyTerminated const&) | ||||
| 	{ | ||||
| 		reason = TerminationReason::ExplicitlyTerminated; | ||||
| 	} | ||||
| 
 | ||||
| 	state.dumpTraceAndState(_os); | ||||
| 	return reason; | ||||
| } | ||||
|  | ||||
| @ -25,7 +25,15 @@ namespace yul_fuzzer | ||||
| { | ||||
| struct yulFuzzerUtil | ||||
| { | ||||
| 	static void interpret( | ||||
| 	enum class TerminationReason | ||||
| 	{ | ||||
| 		ExplicitlyTerminated, | ||||
| 		StepLimitReached, | ||||
| 		TraceLimitReached, | ||||
| 		None | ||||
| 	}; | ||||
| 
 | ||||
| 	static TerminationReason interpret( | ||||
| 		std::ostream& _os, | ||||
| 		std::shared_ptr<yul::Block> _ast, | ||||
| 		Dialect const& _dialect, | ||||
|  | ||||
| @ -66,9 +66,6 @@ DEFINE_PROTO_FUZZER(Program const& _input) | ||||
| 		of.write(yul_source.data(), yul_source.size()); | ||||
| 	} | ||||
| 
 | ||||
| 	if (yul_source.size() > 1200) | ||||
| 		return; | ||||
| 
 | ||||
| 	YulStringRepository::reset(); | ||||
| 
 | ||||
| 	// AssemblyStack entry point
 | ||||
| @ -95,35 +92,22 @@ DEFINE_PROTO_FUZZER(Program const& _input) | ||||
| 
 | ||||
| 	ostringstream os1; | ||||
| 	ostringstream os2; | ||||
| 	try | ||||
| 	{ | ||||
| 		yulFuzzerUtil::interpret( | ||||
| 			os1, | ||||
| 			stack.parserResult()->code, | ||||
| 			EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()) | ||||
| 		); | ||||
| 	} | ||||
| 	catch (yul::test::StepLimitReached const&) | ||||
| 	{ | ||||
| 	yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret( | ||||
| 		os1, | ||||
| 		stack.parserResult()->code, | ||||
| 		EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()) | ||||
| 	); | ||||
| 
 | ||||
| 	if (termReason == yulFuzzerUtil::TerminationReason::StepLimitReached) | ||||
| 		return; | ||||
| 	} | ||||
| 	catch (yul::test::InterpreterTerminatedGeneric const&) | ||||
| 	{ | ||||
| 	} | ||||
| 
 | ||||
| 	stack.optimize(); | ||||
| 	try | ||||
| 	{ | ||||
| 		yulFuzzerUtil::interpret( | ||||
| 			os2, | ||||
| 			stack.parserResult()->code, | ||||
| 			EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), | ||||
| 			(yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 1.5) | ||||
| 		); | ||||
| 	} | ||||
| 	catch (yul::test::InterpreterTerminatedGeneric const&) | ||||
| 	{ | ||||
| 	} | ||||
| 	termReason = yulFuzzerUtil::interpret( | ||||
| 		os2, | ||||
| 		stack.parserResult()->code, | ||||
| 		EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion()), | ||||
| 		(yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 1.5) | ||||
| 	); | ||||
| 
 | ||||
| 	bool isTraceEq = (os1.str() == os2.str()); | ||||
| 	yulAssert(isTraceEq, "Interpreted traces for optimized and unoptimized code differ."); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user