Permit partial fuzzing of tests with libraries.

This commit is contained in:
Bhargava Shastry 2021-03-25 09:28:48 +01:00
parent 98a452d0aa
commit 319b0fb624
3 changed files with 51 additions and 23 deletions

View File

@ -154,30 +154,39 @@ evmc::result EvmoneUtility::deployAndExecute(
return callResult;
}
optional<evmc::result> EvmoneUtility::compileAndDeployLibrary()
{
solAssert(!m_libraryName.empty(), "SolidityEvmoneInterface: No library set.");
m_compilationFramework.contractName(m_libraryName);
auto compilationOutput = m_compilationFramework.compileContract();
m_compilationFramework.contractName(m_contractName);
if (compilationOutput.has_value())
{
CompilerOutput cOutput = compilationOutput.value();
// Deploy contract and signal failure if deploy failed
evmc::result createResult = deployContract(cOutput.byteCode);
solAssert(
createResult.status_code == EVMC_SUCCESS,
"SolidityEvmoneInterface: Library deployment failed"
);
m_compilationFramework.libraryAddresses(
{{m_libraryName, EVMHost::convertFromEVMC(createResult.create_address)}}
);
return createResult;
}
else
return nullopt;
}
optional<evmc::result> EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle)
{
map<string, h160> libraryAddressMap;
// Stage 1: Compile and deploy library if present.
// Stage 1: Deploy library if it exists.
if (!m_libraryName.empty())
{
m_compilationFramework.contractName(m_libraryName);
auto compilationOutput = m_compilationFramework.compileContract();
if (compilationOutput.has_value())
{
CompilerOutput cOutput = compilationOutput.value();
// Deploy contract and signal failure if deploy failed
evmc::result createResult = deployContract(cOutput.byteCode);
solAssert(
createResult.status_code == EVMC_SUCCESS,
"SolidityEvmoneInterface: Library deployment failed"
);
libraryAddressMap[m_libraryName] = EVMHost::convertFromEVMC(createResult.create_address);
m_compilationFramework.libraryAddresses(libraryAddressMap);
}
else
return {};
auto r = compileAndDeployLibrary();
if (!r.has_value())
return r;
}
// Stage 2: Compile, deploy, and execute contract, optionally using library
// address map.
m_compilationFramework.contractName(m_contractName);

View File

@ -218,6 +218,9 @@ public:
/// identifiers for methods in @param _contractName.
std::optional<CompilerOutput> compileContract();
/// Compiles and deploys library on blockchain.
std::optional<evmc::result> compileAndDeployLibrary();
private:
/// EVM Host implementation

View File

@ -34,6 +34,7 @@
#include <abicoder.hpp>
#include <regex>
#include <sstream>
using namespace solidity::frontend::test;
@ -54,9 +55,12 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
// if (_size <= 600)
{
string input(reinterpret_cast<char const*>(_data), _size);
// TODO: Cannot fuzz tests containing libraries yet.
if (input.find("library") != string::npos)
return 0;
regex re = regex("library\\s*(\\w+)\\s*\\{");
smatch matches;
std::string libraryName;
auto match = regex_search(input, matches, re);
if (match && matches[1].matched)
libraryName = matches[1].str();
map<string, string> sourceCode;
try
@ -82,10 +86,22 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
hostContext,
cInput,
contractName,
{},
libraryName,
methodName
);
if (!libraryName.empty())
{
cout << "Deploying library" << endl;
auto l = evmoneUtil.compileAndDeployLibrary();
if (!l.has_value())
return 0;
cout << "Deployed" << endl;
}
hostContext.reset();
evmoneUtil.reset(true);
evmoneUtil.optSetting(compilerSetting);
auto compilerOutput = evmoneUtil.compileContract();
if (!compilerOutput.has_value())
return 0;