From 9bfab1fe00dfd7b67027cea532addbad0867484d Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Mon, 4 May 2020 15:31:06 +0200 Subject: [PATCH] Permit u256 constants --- liblangutil/Exceptions.h | 1 + test/tools/ossfuzz/solArithProtoFuzzer.cpp | 58 ++++++++++++---------- test/tools/ossfuzz/solarithprotoToSol.cpp | 27 +++++----- test/tools/ossfuzz/solarithprotoToSol.h | 23 ++++++++- 4 files changed, 69 insertions(+), 40 deletions(-) diff --git a/liblangutil/Exceptions.h b/liblangutil/Exceptions.h index b8688afa6..8e5081985 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -37,6 +37,7 @@ namespace solidity::langutil class Error; using ErrorList = std::vector>; +struct FuzzerError: virtual util::Exception {}; struct CompilerError: virtual util::Exception {}; struct InternalCompilerError: virtual util::Exception {}; struct FatalError: virtual util::Exception {}; diff --git a/test/tools/ossfuzz/solArithProtoFuzzer.cpp b/test/tools/ossfuzz/solArithProtoFuzzer.cpp index d71cec4e9..d65c2e775 100644 --- a/test/tools/ossfuzz/solArithProtoFuzzer.cpp +++ b/test/tools/ossfuzz/solArithProtoFuzzer.cpp @@ -123,9 +123,9 @@ std::pair compileContract( ); } // Ignore stack too deep errors during compilation - catch (evmasm::StackTooDeepException const&) + catch (Exception const&) { - return std::make_pair(bytes{}, Json::Value(0)); + throw langutil::FuzzerError(); } } @@ -225,31 +225,37 @@ DEFINE_PROTO_FUZZER(Program const& _input) std::cout << sol_source << std::endl; } - auto minimalResult = compileDeployAndExecute( - sol_source, - ":C", - "test()", - frontend::OptimiserSettings::minimal(), - "" - ); - bool successState = minimalResult.status_code == EVMC_SUCCESS; + try { + auto minimalResult = compileDeployAndExecute( + sol_source, + ":C", + "test()", + frontend::OptimiserSettings::minimal(), + "" + ); + bool successState = minimalResult.status_code == EVMC_SUCCESS; - auto optResult = compileDeployAndExecute( - sol_source, - ":C", - "test()", - frontend::OptimiserSettings::standard(), - "" - ); - if (successState) - { - solAssert( - optResult.status_code == EVMC_SUCCESS, - "Sol arith fuzzer: Optimal code failed" - ); - solAssert( - compareRuns(minimalResult, optResult), - "Sol arith fuzzer: Runs produced different result" + auto optResult = compileDeployAndExecute( + sol_source, + ":C", + "test()", + frontend::OptimiserSettings::standard(), + "" ); + if (successState) + { + solAssert( + optResult.status_code == EVMC_SUCCESS, + "Sol arith fuzzer: Optimal code failed" + ); + solAssert( + compareRuns(minimalResult, optResult), + "Sol arith fuzzer: Runs produced different result" + ); + } } + catch (langutil::FuzzerError const&) + { + } + } \ No newline at end of file diff --git a/test/tools/ossfuzz/solarithprotoToSol.cpp b/test/tools/ossfuzz/solarithprotoToSol.cpp index b411e2f26..444693f95 100644 --- a/test/tools/ossfuzz/solarithprotoToSol.cpp +++ b/test/tools/ossfuzz/solarithprotoToSol.cpp @@ -84,7 +84,7 @@ string ProtoConverter::visit(VarDecl const& _vardecl) m_varTypeMap.emplace(varName, pair(typeSign(_vardecl.t()), type)); v("type", type); v("varName", varName); - v("value", varExists ? visit(_vardecl.value()) : to_string((*m_rand)())); + v("value", varExists ? visit(_vardecl.value()) : maskUnsignedToHex(64)); incrementVarCounter(); return "\t\t" + v.render() + '\n'; } @@ -142,19 +142,19 @@ string ProtoConverter::visit(BinaryOp const& _bop) auto left = visit(_bop.left()); auto right = visit(_bop.right()); - Sign leftSign = m_exprSignMap[&_bop.left()]; - Sign rightSign = m_exprSignMap[&_bop.right()]; + Sign leftSign = m_exprSignMap[&_bop.left()].first; + string leftSignString = m_exprSignMap[&_bop.left()].second; + Sign rightSign = m_exprSignMap[&_bop.right()].first; + string rightSignString = m_exprSignMap[&_bop.right()].second; - bool expSignChange = _bop.op() == BinaryOp_Op_EXP && rightSign == Sign::Signed; + bool expOrMod = binaryOperandExp(_bop.op()); + bool expSignChange = expOrMod && rightSign == Sign::Signed; if (expSignChange) - { right = Whiskers(R"(uint())")("expr", right).render(); - rightSign = Sign::Unsigned; - } - if (leftSign != rightSign && _bop.op() != BinaryOp_Op_EXP) - right = signString(leftSign) + "(" + right + ")"; + else if (!expOrMod || leftSign == Sign::Unsigned) + right = leftSignString + "(" + right + ")"; - return left + op + right; + return '(' + left + op + right + ')'; } string ProtoConverter::visit(Expression const& _expr) @@ -166,7 +166,7 @@ string ProtoConverter::visit(Expression const& _expr) solAssert(varAvailable(), "Sol arith fuzzer: Varref unavaileble"); string v = visit(_expr.v()); if (!m_exprSignMap.count(&_expr)) - m_exprSignMap.emplace(&_expr, m_varTypeMap[v].first); + m_exprSignMap.emplace(&_expr, m_varTypeMap[v]); return v; } case Expression::kBop: @@ -179,8 +179,9 @@ string ProtoConverter::visit(Expression const& _expr) } case Expression::EXPR_ONEOF_NOT_SET: { - m_exprSignMap.emplace(&_expr, m_varTypeMap["v0"].first); - return "v0"; + if (!m_exprSignMap.count(&_expr)) + m_exprSignMap.emplace(&_expr, pair(Sign::Unsigned, "uint")); + return maskUnsignedToHex(64); } } } diff --git a/test/tools/ossfuzz/solarithprotoToSol.h b/test/tools/ossfuzz/solarithprotoToSol.h index 987d91291..23421b50a 100644 --- a/test/tools/ossfuzz/solarithprotoToSol.h +++ b/test/tools/ossfuzz/solarithprotoToSol.h @@ -1,5 +1,8 @@ #include +#include +#include +#include #include namespace solidity::test::solarithfuzzer @@ -109,11 +112,29 @@ private: { return _ts.s() == Type::SIGNED ? Sign::Signed : Sign::Unsigned; } + std::string maskUnsignedToHex(unsigned _numMaskNibbles) + { + return toHex(maskUnsignedInt(_numMaskNibbles), util::HexPrefix::Add); + } + bool binaryOperandExp(BinaryOp::Op _op) + { + return _op == BinaryOp_Op_EXP; + } + + // Convert _counter to string and return its keccak256 hash + solidity::u256 hashUnsignedInt() + { + return util::keccak256(util::h256((*m_rand)())); + } + u256 maskUnsignedInt(unsigned _numMaskNibbles) + { + return hashUnsignedInt() & u256("0x" + std::string(_numMaskNibbles, 'f')); + } unsigned m_varCounter = 0; std::shared_ptr m_rand; std::map> m_varTypeMap; - std::map m_exprSignMap; + std::map> m_exprSignMap; std::string m_returnType; }; } \ No newline at end of file