diff options
Diffstat (limited to 'test/libsolidity/SolidityEndToEndTest.cpp')
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 137 |
1 files changed, 122 insertions, 15 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index ed95d687..6478ea86 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1,18 +1,18 @@ /* - This file is part of cpp-ethereum. + This file is part of solidity. - cpp-ethereum is free software: you can redistribute it and/or modify + solidity is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, + solidity is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. + along with solidity. If not, see <http://www.gnu.org/licenses/>. */ /** * @author Christian <c@ethdev.com> @@ -1337,6 +1337,7 @@ BOOST_AUTO_TEST_CASE(struct_accessor) BOOST_AUTO_TEST_CASE(balance) { char const* sourceCode = "contract test {\n" + " function test() payable {}\n" " function getBalance() returns (uint256 balance) {\n" " return address(this).balance;\n" " }\n" @@ -1348,6 +1349,7 @@ BOOST_AUTO_TEST_CASE(balance) BOOST_AUTO_TEST_CASE(blockchain) { char const* sourceCode = "contract test {\n" + " function test() payable {}\n" " function someInfo() payable returns (uint256 value, address coinbase, uint256 blockNumber) {\n" " value = msg.value;\n" " coinbase = block.coinbase;\n" @@ -1563,6 +1565,7 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_greater_size) BOOST_AUTO_TEST_CASE(send_ether) { char const* sourceCode = "contract test {\n" + " function test() payable {}\n" " function a(address addr, uint amount) returns (uint ret) {\n" " addr.send(amount);\n" " return address(this).balance;\n" @@ -1675,6 +1678,7 @@ BOOST_AUTO_TEST_CASE(log_in_constructor) BOOST_AUTO_TEST_CASE(suicide) { char const* sourceCode = "contract test {\n" + " function test() payable {}\n" " function a(address receiver) returns (uint ret) {\n" " suicide(receiver);\n" " return 10;\n" @@ -1691,6 +1695,7 @@ BOOST_AUTO_TEST_CASE(suicide) BOOST_AUTO_TEST_CASE(selfdestruct) { char const* sourceCode = "contract test {\n" + " function test() payable {}\n" " function a(address receiver) returns (uint ret) {\n" " selfdestruct(receiver);\n" " return 10;\n" @@ -2956,24 +2961,24 @@ BOOST_AUTO_TEST_CASE(generic_call) BOOST_AUTO_TEST_CASE(generic_callcode) { char const* sourceCode = R"**( - contract receiver { + contract Receiver { uint public received; function receive(uint256 x) payable { received = x; } } - contract sender { + contract Sender { uint public received; - function sender() payable { } + function Sender() payable { } function doSend(address rec) returns (uint d) { bytes4 signature = bytes4(bytes32(sha3("receive(uint256)"))); rec.callcode.value(2)(signature, 23); - return receiver(rec).received(); + return Receiver(rec).received(); } } )**"; - compileAndRun(sourceCode, 0, "receiver"); + compileAndRun(sourceCode, 0, "Receiver"); u160 const c_receiverAddress = m_contractAddress; - compileAndRun(sourceCode, 50, "sender"); + compileAndRun(sourceCode, 50, "Sender"); u160 const c_senderAddress = m_contractAddress; BOOST_CHECK(callContractFunction("doSend(address)", c_receiverAddress) == encodeArgs(0)); BOOST_CHECK(callContractFunction("received()") == encodeArgs(23)); @@ -2988,16 +2993,18 @@ BOOST_AUTO_TEST_CASE(generic_callcode) BOOST_AUTO_TEST_CASE(generic_delegatecall) { char const* sourceCode = R"**( - contract receiver { + contract Receiver { uint public received; address public sender; uint public value; + function Receiver() payable {} function receive(uint256 x) payable { received = x; sender = msg.sender; value = msg.value; } } - contract sender { + contract Sender { uint public received; address public sender; uint public value; + function Sender() payable {} function doSend(address rec) payable { bytes4 signature = bytes4(bytes32(sha3("receive(uint256)"))); @@ -3005,9 +3012,9 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall) } } )**"; - compileAndRun(sourceCode, 0, "receiver"); + compileAndRun(sourceCode, 0, "Receiver"); u160 const c_receiverAddress = m_contractAddress; - compileAndRun(sourceCode, 50, "sender"); + compileAndRun(sourceCode, 50, "Sender"); u160 const c_senderAddress = m_contractAddress; BOOST_CHECK(m_sender != c_senderAddress); // just for sanity BOOST_CHECK(callContractFunctionWithValue("doSend(address)", 11, c_receiverAddress) == encodeArgs()); @@ -4499,6 +4506,102 @@ BOOST_AUTO_TEST_CASE(external_types_in_calls) BOOST_CHECK(callContractFunction("t2()") == encodeArgs(u256(9))); } +BOOST_AUTO_TEST_CASE(invalid_enum_compared) +{ + char const* sourceCode = R"( + contract C { + enum X { A, B } + + function test_eq() returns (bool) { + X garbled; + assembly { + garbled := 5 + } + return garbled == garbled; + } + function test_eq_ok() returns (bool) { + X garbled = X.A; + return garbled == garbled; + } + function test_neq() returns (bool) { + X garbled; + assembly { + garbled := 5 + } + return garbled != garbled; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test_eq_ok()") == encodeArgs(u256(1))); + // both should throw + BOOST_CHECK(callContractFunction("test_eq()") == encodeArgs()); + BOOST_CHECK(callContractFunction("test_neq()") == encodeArgs()); +} + +BOOST_AUTO_TEST_CASE(invalid_enum_logged) +{ + char const* sourceCode = R"( + contract C { + enum X { A, B } + event Log(X); + + function test_log() returns (uint) { + X garbled = X.A; + assembly { + garbled := 5 + } + Log(garbled); + return 1; + } + function test_log_ok() returns (uint) { + X x = X.A; + Log(x); + return 1; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test_log_ok()") == encodeArgs(u256(1))); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_REQUIRE_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Log(uint8)"))); + BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(0))); + + // should throw + BOOST_CHECK(callContractFunction("test_log()") == encodeArgs()); +} + +BOOST_AUTO_TEST_CASE(invalid_enum_stored) +{ + char const* sourceCode = R"( + contract C { + enum X { A, B } + X public x; + + function test_store() returns (uint) { + X garbled = X.A; + assembly { + garbled := 5 + } + x = garbled; + return 1; + } + function test_store_ok() returns (uint) { + x = X.A; + return 1; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test_store_ok()") == encodeArgs(u256(1))); + BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(0))); + + // should throw + BOOST_CHECK(callContractFunction("test_store()") == encodeArgs()); +} + BOOST_AUTO_TEST_CASE(invalid_enum_as_external_ret) { char const* sourceCode = R"( @@ -4818,6 +4921,7 @@ BOOST_AUTO_TEST_CASE(failing_send) } } contract Main { + function Main() payable {} function callHelper(address _a) returns (bool r, uint bal) { r = !_a.send(5); bal = this.balance; @@ -4840,6 +4944,7 @@ BOOST_AUTO_TEST_CASE(send_zero_ether) } } contract Main { + function Main() payable {} function s() returns (bool) { var r = new Receiver(); return r.send(0); @@ -6341,6 +6446,7 @@ BOOST_AUTO_TEST_CASE(reject_ether_sent_to_library) char const* sourceCode = R"( library lib {} contract c { + function c() payable {} function f(address x) returns (bool) { return x.send(1); } @@ -7279,6 +7385,7 @@ BOOST_AUTO_TEST_CASE(failed_create) contract D { function D() payable {} } contract C { uint public x; + function C() payable {} function f(uint amount) returns (address) { x++; return (new D).value(amount)(); @@ -7392,7 +7499,7 @@ BOOST_AUTO_TEST_CASE(mutex) } contract Fund is mutexed { uint shares; - function Fund() { shares = msg.value; } + function Fund() payable { shares = msg.value; } function withdraw(uint amount) protected returns (uint) { // NOTE: It is very bad practice to write this function this way. // Please refer to the documentation of how to do this properly. |