Refactor contract ABI Utils a bit to get it to build with solc ossfuzz. Untested.

This commit is contained in:
Bhargava Shastry 2021-03-12 10:36:21 +01:00
parent 39fcdf22c3
commit ee665748aa
8 changed files with 46 additions and 15 deletions

View File

@ -44,6 +44,7 @@ struct InternalCompilerError: virtual util::Exception {};
struct FatalError: virtual util::Exception {};
struct UnimplementedFeatureError: virtual util::Exception {};
struct InvalidAstError: virtual util::Exception {};
struct TestFrameworkError: virtual util::Exception {};
/// Assertion that throws an InternalCompilerError containing the given description if it is not met.
#define solAssert(CONDITION, DESCRIPTION) \

View File

@ -30,6 +30,7 @@
#include <libsolidity/interface/DebugSettings.h>
#include <liblangutil/EVMVersion.h>
#include <liblangutil/Exceptions.h>
#include <libsolutil/FixedHash.h>
#include <libsolutil/Keccak256.h>
@ -37,13 +38,6 @@
#include <functional>
#include <boost/test/unit_test.hpp>
namespace solidity::frontend::test
{
struct LogRecord;
} // namespace solidity::frontend::test
namespace solidity::test
{
using rational = boost::rational<bigint>;
@ -84,8 +78,8 @@ public:
_arguments,
_libraryAddresses
);
BOOST_REQUIRE(m_transactionSuccessful);
BOOST_REQUIRE(!m_output.empty());
assertThrow(m_transactionSuccessful, langutil::TestFrameworkError, "");
assertThrow(!m_output.empty(), langutil::TestFrameworkError, "");
return m_output;
}
@ -135,8 +129,9 @@ public:
{
bytes contractResult = callContractFunction(_sig, _arguments...);
bytes cppResult = callCppAndEncodeResult(_cppFunction, _arguments...);
BOOST_CHECK_MESSAGE(
assertThrow(
contractResult == cppResult,
langutil::TestFrameworkError,
"Computed values do not match.\nContract: " +
util::toHex(contractResult) +
"\nC++: " +
@ -151,8 +146,9 @@ public:
{
bytes contractResult = callContractFunction(_sig, argument);
bytes cppResult = callCppAndEncodeResult(_cppFunction, argument);
BOOST_CHECK_MESSAGE(
assertThrow(
contractResult == cppResult,
langutil::TestFrameworkError,
"Computed values do not match.\nContract: " +
util::toHex(contractResult) +
"\nC++: " +
@ -311,7 +307,11 @@ protected:
#define ABI_CHECK(result, expectation) do { \
auto abiCheckResult = ExecutionFramework::compareAndCreateMessage((result), (expectation)); \
BOOST_CHECK_MESSAGE(abiCheckResult.first, abiCheckResult.second); \
assertThrow( \
abiCheckResult.first == abiCheckResult.second, \
langutil::TestFrameworkError, \
""\
); \
} while (0)

View File

@ -124,7 +124,9 @@ bool isFixedTupleArray(string const& _type)
return regex_match(_type, regex{"tuple\\[\\d+\\]"});
}
string functionSignatureFromABI(Json::Value const& _functionABI)
}
string ContractABIUtils::functionSignatureFromABI(Json::Value const& _functionABI)
{
auto inputs = _functionABI["inputs"];
string signature = {_functionABI["name"].asString() + "("};
@ -141,8 +143,6 @@ string functionSignatureFromABI(Json::Value const& _functionABI)
return signature + ")";
}
}
std::optional<solidity::frontend::test::ParameterList> ContractABIUtils::parametersFromJsonOutputs(
ErrorReporter& _errorReporter,
Json::Value const& _contractABI,

View File

@ -75,6 +75,9 @@ public:
/// on the size of their types.
static size_t encodingSize(ParameterList const& _paremeters);
/// @returns function signature from ABI.
static std::string functionSignatureFromABI(Json::Value const& _functionABI);
private:
/// Parses and translates a single type and returns a list of
/// internal type representations of isoltest.

View File

@ -29,6 +29,7 @@ if (OSSFUZZ)
../../TestCaseReader.cpp
../../EVMHost.cpp
SolidityEvmoneInterface.cpp
../../libsolidity/util/ContractABIUtils.cpp
)
target_link_libraries(solc_ossfuzz PRIVATE libsolc evmasm evmc evmone-standalone)
set_target_properties(solc_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})

View File

@ -23,6 +23,7 @@
#include <range/v3/algorithm/all_of.hpp>
#include <range/v3/span.hpp>
#include <random>
using namespace solidity::test::fuzzer;
using namespace solidity::frontend;
@ -74,6 +75,20 @@ optional<string> SolidityCompilationFramework::noInputFunction()
return {};
}
optional<Json::Value> SolidityCompilationFramework::randomFunction()
{
Json::Value const& contractABI = m_compiler.contractABI(m_compiler.lastContractName());
unsigned numFunctions = contractABI.size();
if (numFunctions == 0)
return {};
else
{
uniform_int_distribution<unsigned> d(0, contractABI.size());
minstd_rand r(contractABI.size());
return contractABI[d(r)];
}
}
bool EvmoneUtility::zeroWord(uint8_t const* _result, size_t _length)
{
return _length == 32 &&

View File

@ -100,6 +100,9 @@ public:
/// @returns name of a public/external method that does not contain
/// input parameters in its signature.
std::optional<std::string> noInputFunction();
/// @returns FunctionABI of a randomly chosen external function in
/// current contract.
std::optional<Json::Value> randomFunction();
/// @returns name of the last contract in source unit.
std::string lastContractName()
{
@ -178,6 +181,10 @@ public:
{
return m_compilationFramework.noInputFunction();
}
std::optional<Json::Value> randomFunction()
{
return m_compilationFramework.randomFunction();
}
void optSetting(frontend::OptimiserSettings _opt)
{
m_compilationFramework.optSetting(_opt);

View File

@ -22,6 +22,8 @@
#include <test/TestCaseReader.h>
#include <libsolidity/util/ContractABIUtils.h>
#include <libyul/backends/evm/EVMCodeTransform.h>
#include <liblangutil/EVMVersion.h>
@ -84,6 +86,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* _data, size_t _size)
return 0;
optional<string> noInputFunction = evmoneUtil.noInputFunction();
if (auto r = evmoneUtil.randomFunction(); r.has_value())
cout << ContractABIUtils{}.functionSignatureFromABI(r.value()) << endl;
if (noInputFunction.has_value())
evmoneUtil.methodName(noInputFunction.value());
else