From 7dd200d140725a326b31cc6bf07e56d820627854 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 14 Feb 2015 00:43:02 +0100 Subject: [PATCH 1/4] "external" visibility specifier. --- SolidityNameAndTypeResolution.cpp | 50 +++++++++++++++++++++++++++++++ SolidityParser.cpp | 18 +++++++++++ 2 files changed, 68 insertions(+) diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index d6e4ed516..f30de96ce 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -1083,6 +1083,56 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError); } +BOOST_AUTO_TEST_CASE(private_visibility) +{ + char const* sourceCode = R"( + contract base { + function f() private {} + } + contract derived is base { + function g() { f(); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError); +} + +BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access) +{ + char const* sourceCode = R"( + contract base { + function f() private {} + } + contract derived is base { + function g() { base.f(); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(external_visibility) +{ + char const* sourceCode = R"( + contract c { + function f() external {} + function g() { f(); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError); +} + +BOOST_AUTO_TEST_CASE(external_base_visibility) +{ + char const* sourceCode = R"( + contract base { + function f() external {} + } + contract derived is base { + function g() { base.f(); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/SolidityParser.cpp b/SolidityParser.cpp index af82f612a..5f9064e0c 100644 --- a/SolidityParser.cpp +++ b/SolidityParser.cpp @@ -735,6 +735,24 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration) BOOST_CHECK_THROW(parseText(text), ParserError); } +BOOST_AUTO_TEST_CASE(external_function) +{ + char const* text = R"( + contract c { + function x() external {} + })"; + BOOST_CHECK_NO_THROW(parseTextExplainError(text)); +} + +BOOST_AUTO_TEST_CASE(external_variable) +{ + char const* text = R"( + contract c { + uint external x; + })"; + BOOST_CHECK_THROW(parseText(text), ParserError); +} + BOOST_AUTO_TEST_SUITE_END() } From 8290b6305bfa66cbff74a5c61cca88d968224a8b Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 14 Feb 2015 01:22:44 +0100 Subject: [PATCH 2/4] No write access to parameters of external functions. --- SolidityEndToEndTest.cpp | 15 +++++++++++++++ SolidityNameAndTypeResolution.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index 0325c4c6a..9899af29f 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -2534,6 +2534,21 @@ BOOST_AUTO_TEST_CASE(constructing_enums_from_ints) BOOST_CHECK(callContractFunction("test()") == encodeArgs(1)); } +BOOST_AUTO_TEST_CASE(external_function) +{ + char const* sourceCode = R"( + contract c { + function f(uint a) returns (uint) { return a; } + function test(uint a, uint b) external returns (uint r_a, uint r_b) { + r_a = f(a + 7); + r_b = b; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", 2, 3) == encodeArgs(2, 3+7)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index f30de96ce..6b337ac74 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -1133,6 +1133,36 @@ BOOST_AUTO_TEST_CASE(external_base_visibility) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(external_argument_assign) +{ + char const* sourceCode = R"( + contract c { + function f(uint a) external { a = 1; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(external_argument_increment) +{ + char const* sourceCode = R"( + contract c { + function f(uint a) external { a++; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(external_argument_delete) +{ + char const* sourceCode = R"( + contract c { + function f(uint a) external { delete a; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From 5f043127ae0ee87e3654978dceafb67c8c1d314a Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 15 Feb 2015 01:02:38 +0100 Subject: [PATCH 3/4] loadFromMemoryDynamic --- SolidityCompiler.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/SolidityCompiler.cpp b/SolidityCompiler.cpp index 17d9a7c07..1369b038f 100644 --- a/SolidityCompiler.cpp +++ b/SolidityCompiler.cpp @@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) "}\n"; bytes code = compileContract(sourceCode); - unsigned boilerplateSize = 69; + unsigned boilerplateSize = 70; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, // initialize local variable x byte(Instruction::PUSH1), 0x2, @@ -114,8 +114,8 @@ BOOST_AUTO_TEST_CASE(ifStatement) " function f() { bool x; if (x) 77; else if (!x) 78; else 79; }" "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 56; - unsigned boilerplateSize = 69; + unsigned shift = 57; + unsigned boilerplateSize = 70; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, byte(Instruction::DUP1), @@ -155,8 +155,8 @@ BOOST_AUTO_TEST_CASE(loops) " function f() { while(true){1;break;2;continue;3;return;4;} }" "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 56; - unsigned boilerplateSize = 69; + unsigned shift = 57; + unsigned boilerplateSize = 70; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x1, From 9d0bb3666ebf9d463ef25dd699f0d6fb1368dbcd Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 16 Feb 2015 17:33:13 +0100 Subject: [PATCH 4/4] Calldata byte arrays stored on the stack. --- SolidityEndToEndTest.cpp | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index 9899af29f..103b11269 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -2283,9 +2283,9 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) } )"; compileAndRun(sourceCode); - bytes calldata = bytes(61, 0x22) + bytes(12, 0x12); - sendMessage(calldata, false); - BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata))); + bytes calldata1 = bytes(61, 0x22) + bytes(12, 0x12); + sendMessage(calldata1, false); + BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata1))); } BOOST_AUTO_TEST_CASE(call_forward_bytes) @@ -2546,7 +2546,35 @@ BOOST_AUTO_TEST_CASE(external_function) } )"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("test(uint256,uint256)", 2, 3) == encodeArgs(2, 3+7)); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", 2, 3) == encodeArgs(2+7, 3)); +} + +BOOST_AUTO_TEST_CASE(bytes_in_arguments) +{ + char const* sourceCode = R"( + contract c { + uint result; + function f(uint a, uint b) { result += a + b; } + function g(uint a) { result *= a; } + function test(uint a, bytes data1, bytes data2, uint b) external returns (uint r_a, uint r, uint r_b, uint l) { + r_a = a; + this.call(data1); + this.call(data2); + r = result; + r_b = b; + l = data1.length; + } + } + )"; + compileAndRun(sourceCode); + string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9)); + bytes calldata1 = encodeArgs(u256(innercalldata1.length()), 12, innercalldata1, 13); + string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3)); + bytes calldata = encodeArgs( + u256(innercalldata1.length()), u256(innercalldata2.length()), + 12, innercalldata1, innercalldata2, 13); + BOOST_CHECK(callContractFunction("test(uint256,bytes,bytes,uint256)", calldata) + == encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length()))); } BOOST_AUTO_TEST_SUITE_END()