diff --git a/test/tools/ossfuzz/SolidityGenerator.cpp b/test/tools/ossfuzz/SolidityGenerator.cpp index 5b50cb82a..e3d222456 100644 --- a/test/tools/ossfuzz/SolidityGenerator.cpp +++ b/test/tools/ossfuzz/SolidityGenerator.cpp @@ -182,6 +182,9 @@ string ImportGenerator::visit() << importPath << "\";\n"; state->sourceUnitState[state->currentPath()]->addImportedSourcePath(importPath); + state->sourceUnitState[state->currentPath()]->resolveImports( + state->sourceUnitState[importPath]->exports + ); } return os.str(); } @@ -204,9 +207,15 @@ string ContractGenerator::visit() mutator->generator()->scope(false); }; ostringstream os; + string inheritance; + if (state->sourceUnitState[state->currentPath()]->contractType()) + inheritance = state->sourceUnitState[state->currentPath()]->randomContract(); string name = state->newContract(); state->updateContract(name); - os << "contract " << name << " {" << endl; + os << "contract " << name; + if (!inheritance.empty()) + os << " is " << inheritance; + os << " {" << endl; set(); os << visitChildren(); os << "}" << endl; diff --git a/test/tools/ossfuzz/SolidityGenerator.h b/test/tools/ossfuzz/SolidityGenerator.h index b18352ab1..69beb71f1 100644 --- a/test/tools/ossfuzz/SolidityGenerator.h +++ b/test/tools/ossfuzz/SolidityGenerator.h @@ -30,7 +30,11 @@ #include #include #include + +#include +#include #include +#include namespace solidity::test::fuzzer::mutator { @@ -113,12 +117,16 @@ struct ContractState std::shared_ptr uRandDist; }; -struct Type {}; +struct Type +{ + virtual ~Type() {} +}; struct FunctionType: Type { std::vector inputs; std::vector outputs; }; +struct ContractType: Type {}; struct SourceState { @@ -134,10 +142,32 @@ struct SourceState { return !(exports | ranges::views::filter([&_functionName](auto& _p) { return _p.second == _functionName; })).empty(); } + bool contractType() + { + return !(exports | ranges::views::filter([](auto& _i) { + return bool(std::dynamic_pointer_cast(_i.first)); + })).empty(); + } + std::string randomContract() + { + auto contracts = exports | + ranges::views::filter([](auto& _item) -> bool { + return bool(std::dynamic_pointer_cast(_item.first)); + }) | + ranges::views::transform([](auto& _item) -> std::string { + return _item.second; + }) | ranges::to>; + return contracts[uRandDist->distributionOneToN(contracts.size()) - 1]; + } void addImportedSourcePath(std::string& _sourcePath) { importedSources.emplace(_sourcePath); } + void resolveImports(std::map, std::string> _imports) + { + for (auto const& item: _imports) + exports.emplace(item); + } [[nodiscard]] bool sourcePathImported(std::string const& _sourcePath) const { return importedSources.count(_sourcePath); @@ -181,6 +211,7 @@ struct TestState void addContract(std::string const& _name) { contractState.emplace(_name, std::make_shared(uRandDist)); + sourceUnitState[currentSourceUnitPath]->exports[std::make_shared()] = _name; currentContract = _name; } void addFunction(std::string const& _name)