| 67 | } |
| 68 | |
| 69 | DEFINE_PROTO_FUZZER(Program const& _input) |
| 70 | { |
| 71 | // Solidity creates an invalid instruction for subobjects, so we simply |
| 72 | // ignore them in this fuzzer. |
| 73 | if (_input.has_obj()) |
| 74 | return; |
| 75 | bool filterStatefulInstructions = true; |
| 76 | bool filterUnboundedLoops = true; |
| 77 | ProtoConverter converter( |
| 78 | filterStatefulInstructions, |
| 79 | filterUnboundedLoops |
| 80 | ); |
| 81 | std::string yul_source = converter.programToString(_input); |
| 82 | // Do not fuzz the EVM Version field. |
| 83 | // See https://github.com/argotorg/solidity/issues/12590 |
| 84 | langutil::EVMVersion version; |
| 85 | EVMHost hostContext(version, evmone); |
| 86 | hostContext.reset(); |
| 87 | |
| 88 | if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) |
| 89 | { |
| 90 | std::ofstream of(dump_path); |
| 91 | of.write(yul_source.data(), static_cast<std::streamsize>(yul_source.size())); |
| 92 | } |
| 93 | |
| 94 | YulStringRepository::reset(); |
| 95 | |
| 96 | solidity::frontend::OptimiserSettings settings = solidity::frontend::OptimiserSettings::full(); |
| 97 | settings.runYulOptimiser = false; |
| 98 | settings.optimizeStackAllocation = false; |
| 99 | bytes unoptimisedByteCode; |
| 100 | bool recursiveFunction = false; |
| 101 | bool unoptimizedStackTooDeep = false; |
| 102 | try |
| 103 | { |
| 104 | YulAssembler assembler{version, std::nullopt, settings, yul_source}; |
| 105 | unoptimisedByteCode = assembler.assemble(); |
| 106 | auto yulObject = assembler.object(); |
| 107 | // TODO: Add EOF support |
| 108 | recursiveFunction = recursiveFunctionExists( |
| 109 | EVMDialect::strictAssemblyForEVMObjects(version, std::nullopt), |
| 110 | *yulObject |
| 111 | ); |
| 112 | } |
| 113 | catch (solidity::yul::StackTooDeepError const&) |
| 114 | { |
| 115 | unoptimizedStackTooDeep = true; |
| 116 | } |
| 117 | |
| 118 | std::ostringstream unoptimizedState; |
| 119 | bool noRevertInSource = true; |
| 120 | bool noInvalidInSource = true; |
| 121 | if (!unoptimizedStackTooDeep) |
| 122 | { |
| 123 | evmc::Result deployResult = YulEvmoneUtility{}.deployCode(unoptimisedByteCode, hostContext); |
| 124 | if (deployResult.status_code != EVMC_SUCCESS) |
| 125 | return; |
| 126 | auto callMessage = YulEvmoneUtility{}.callMessage(deployResult.create_address); |
nothing calls this directly
no test coverage detected