Merge pull request #6822 from ethereum/uninitializedLoadFromStorage

Explicitly turn uninitialized internal function pointers into invalid function when loaded from storage.
This commit is contained in:
chriseth 2019-05-28 11:48:56 +02:00 committed by GitHub
commit b95eebee1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 0 deletions

View File

@ -20,6 +20,7 @@ Compiler Features:
Bugfixes: Bugfixes:
* Code Generator: Explicitly turn uninitialized internal function pointers into invalid functions when loaded from storage.
* Code Generator: Fix assertion failure when assigning structs containing array of mapping. * Code Generator: Fix assertion failure when assigning structs containing array of mapping.
* SMTChecker: Fix bad cast in base constructor modifier. * SMTChecker: Fix bad cast in base constructor modifier.
* SMTChecker: Fix internal error when visiting state variable inherited from base class. * SMTChecker: Fix internal error when visiting state variable inherited from base class.

View File

@ -206,6 +206,12 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
CompilerUtils(m_context).splitExternalFunctionType(false); CompilerUtils(m_context).splitExternalFunctionType(false);
cleaned = true; cleaned = true;
} }
else if (fun->kind() == FunctionType::Kind::Internal)
{
m_context << Instruction::DUP1 << Instruction::ISZERO;
CompilerUtils(m_context).pushZeroValue(*fun);
m_context << Instruction::MUL << Instruction::OR;
}
} }
if (!cleaned) if (!cleaned)
{ {

View File

@ -15683,6 +15683,40 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name)
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256)"))); BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256)")));
} }
BOOST_AUTO_TEST_CASE(uninitialized_internal_storage_function)
{
char const* sourceCode = R"(
contract Test {
function() internal x;
function f() public returns (uint r) {
function() internal t = x;
assembly { r := t }
}
}
)";
compileAndRun(sourceCode, 0, "Test");
bytes result = callContractFunction("f()");
BOOST_CHECK(!result.empty());
BOOST_CHECK(result != encodeArgs(0));
}
BOOST_AUTO_TEST_CASE(uninitialized_internal_storage_function_call)
{
char const* sourceCode = R"(
contract Test {
function() internal x;
function f() public returns (uint r) {
x();
return 2;
}
}
)";
compileAndRun(sourceCode, 0, "Test");
ABI_CHECK(callContractFunction("f()"), bytes{});
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }