mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4920 from ethereum/disallow_indexed_ref_v2_for_0_425
Disallow indexed reference types in events when using ABIEncoderV2 (backported)
This commit is contained in:
commit
a1848ac947
@ -1,6 +1,7 @@
|
||||
### 0.4.25 (unreleased)
|
||||
|
||||
Bugfixes:
|
||||
* Type Checker: Report error when using indexed structs in events with experimental ABIEncoderV2. This used to log wrong values.
|
||||
* Type Checker: Report error when using structs in events without experimental ABIEncoderV2. This used to crash or log the wrong values.
|
||||
|
||||
### 0.4.24 (2018-05-16)
|
||||
|
@ -1,4 +1,12 @@
|
||||
[
|
||||
{
|
||||
"name": "EventStructWrongData",
|
||||
"summary": "Using structs in events logged wrong data.",
|
||||
"description": "If a struct is used in an event, the address of the struct is logged instead of the actual data.",
|
||||
"introduced": "0.4.17",
|
||||
"fixed": "0.4.25",
|
||||
"severity": "very low"
|
||||
},
|
||||
{
|
||||
"name": "OneOfTwoConstructorsSkipped",
|
||||
"summary": "If a contract has both a new-style constructor (using the constructor keyword) and an old-style constructor (a function with the same name as the contract) at the same time, one of them will be ignored.",
|
||||
|
@ -389,16 +389,21 @@
|
||||
},
|
||||
"0.4.17": {
|
||||
"bugs": [
|
||||
"EventStructWrongData",
|
||||
"ZeroFunctionSelector"
|
||||
],
|
||||
"released": "2017-09-21"
|
||||
},
|
||||
"0.4.18": {
|
||||
"bugs": [],
|
||||
"bugs": [
|
||||
"EventStructWrongData"
|
||||
],
|
||||
"released": "2017-10-18"
|
||||
},
|
||||
"0.4.19": {
|
||||
"bugs": [],
|
||||
"bugs": [
|
||||
"EventStructWrongData"
|
||||
],
|
||||
"released": "2017-11-30"
|
||||
},
|
||||
"0.4.2": {
|
||||
@ -415,25 +420,34 @@
|
||||
"released": "2016-09-17"
|
||||
},
|
||||
"0.4.20": {
|
||||
"bugs": [],
|
||||
"bugs": [
|
||||
"EventStructWrongData"
|
||||
],
|
||||
"released": "2018-02-14"
|
||||
},
|
||||
"0.4.21": {
|
||||
"bugs": [],
|
||||
"bugs": [
|
||||
"EventStructWrongData"
|
||||
],
|
||||
"released": "2018-03-07"
|
||||
},
|
||||
"0.4.22": {
|
||||
"bugs": [
|
||||
"EventStructWrongData",
|
||||
"OneOfTwoConstructorsSkipped"
|
||||
],
|
||||
"released": "2018-04-16"
|
||||
},
|
||||
"0.4.23": {
|
||||
"bugs": [],
|
||||
"bugs": [
|
||||
"EventStructWrongData"
|
||||
],
|
||||
"released": "2018-04-19"
|
||||
},
|
||||
"0.4.24": {
|
||||
"bugs": [],
|
||||
"bugs": [
|
||||
"EventStructWrongData"
|
||||
],
|
||||
"released": "2018-05-16"
|
||||
},
|
||||
"0.4.3": {
|
||||
|
@ -869,7 +869,17 @@ bool TypeChecker::visit(EventDefinition const& _eventDef)
|
||||
for (ASTPointer<VariableDeclaration> const& var: _eventDef.parameters())
|
||||
{
|
||||
if (var->isIndexed())
|
||||
{
|
||||
numIndexed++;
|
||||
if (
|
||||
_eventDef.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2) &&
|
||||
dynamic_cast<ReferenceType const*>(type(*var).get())
|
||||
)
|
||||
m_errorReporter.typeError(
|
||||
var->location(),
|
||||
"Indexed reference types cannot yet be used with ABIEncoderV2."
|
||||
);
|
||||
}
|
||||
if (!type(*var)->canLiveOutsideStorage())
|
||||
m_errorReporter.typeError(var->location(), "Type is required to live outside storage.");
|
||||
if (!type(*var)->interfaceType(false))
|
||||
|
@ -3516,6 +3516,209 @@ BOOST_AUTO_TEST_CASE(event_really_really_lots_of_data_from_storage)
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_struct_memory_v2)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
struct S { uint a; }
|
||||
event E(S);
|
||||
function createEvent(uint x) public {
|
||||
emit E(S(x));
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(x));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint256))")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_struct_storage_v2)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
struct S { uint a; }
|
||||
event E(S);
|
||||
S s;
|
||||
function createEvent(uint x) public {
|
||||
s.a = x;
|
||||
emit E(s);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(x));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint256))")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_array_memory)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
event E(uint[]);
|
||||
function createEvent(uint x) public {
|
||||
uint[] memory arr = new uint[](3);
|
||||
arr[0] = x;
|
||||
arr[1] = x + 1;
|
||||
arr[2] = x + 2;
|
||||
emit E(arr);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_array_memory_v2)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
event E(uint[]);
|
||||
function createEvent(uint x) public {
|
||||
uint[] memory arr = new uint[](3);
|
||||
arr[0] = x;
|
||||
arr[1] = x + 1;
|
||||
arr[2] = x + 2;
|
||||
emit E(arr);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_memory_v2)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
event E(uint[][]);
|
||||
function createEvent(uint x) public {
|
||||
uint[][] memory arr = new uint[][](2);
|
||||
arr[0] = new uint[](2);
|
||||
arr[1] = new uint[](2);
|
||||
arr[0][0] = x;
|
||||
arr[0][1] = x + 1;
|
||||
arr[1][0] = x + 2;
|
||||
arr[1][1] = x + 3;
|
||||
emit E(arr);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 2, 0x40, 0xa0, 2, x, x + 1, 2, x + 2, x + 3));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[][])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_array_storage)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
event E(uint[]);
|
||||
uint[] arr;
|
||||
function createEvent(uint x) public {
|
||||
arr.length = 3;
|
||||
arr[0] = x;
|
||||
arr[1] = x + 1;
|
||||
arr[2] = x + 2;
|
||||
emit E(arr);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_array_storage_v2)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
event E(uint[]);
|
||||
uint[] arr;
|
||||
function createEvent(uint x) public {
|
||||
arr.length = 3;
|
||||
arr[0] = x;
|
||||
arr[1] = x + 1;
|
||||
arr[2] = x + 2;
|
||||
emit E(arr);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_storage_v2)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
event E(uint[][]);
|
||||
uint[][] arr;
|
||||
function createEvent(uint x) public {
|
||||
arr.length = 2;
|
||||
arr[0].length = 2;
|
||||
arr[1].length = 2;
|
||||
arr[0][0] = x;
|
||||
arr[0][1] = x + 1;
|
||||
arr[1][0] = x + 2;
|
||||
arr[1][1] = x + 3;
|
||||
emit E(arr);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 2, 0x40, 0xa0, 2, x, x + 1, 2, x + 2, x + 3));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[][])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_indexed_string)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
|
@ -0,0 +1,7 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract c {
|
||||
event E(uint[] indexed);
|
||||
}
|
||||
// ----
|
||||
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
|
||||
// TypeError: (59-65): Indexed reference types cannot yet be used with ABIEncoderV2.
|
6
test/libsolidity/syntaxTests/events/event_array_v2.sol
Normal file
6
test/libsolidity/syntaxTests/events/event_array_v2.sol
Normal file
@ -0,0 +1,6 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract c {
|
||||
event E(uint[]);
|
||||
}
|
||||
// ----
|
||||
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
|
@ -0,0 +1,7 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract c {
|
||||
event E(uint[][] indexed);
|
||||
}
|
||||
// ----
|
||||
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
|
||||
// TypeError: (59-67): Indexed reference types cannot yet be used with ABIEncoderV2.
|
@ -0,0 +1,6 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract c {
|
||||
event E(uint[][]);
|
||||
}
|
||||
// ----
|
||||
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
|
@ -0,0 +1,8 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract c {
|
||||
struct S { uint a ; }
|
||||
event E(S indexed);
|
||||
}
|
||||
// ----
|
||||
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
|
||||
// TypeError: (85-86): Indexed reference types cannot yet be used with ABIEncoderV2.
|
7
test/libsolidity/syntaxTests/events/event_struct_v2.sol
Normal file
7
test/libsolidity/syntaxTests/events/event_struct_v2.sol
Normal file
@ -0,0 +1,7 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract c {
|
||||
struct S { uint a ; }
|
||||
event E(S);
|
||||
}
|
||||
// ----
|
||||
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
|
Loading…
Reference in New Issue
Block a user