From 9e32aa7510ffa4dc713c2b75059db20f3158e6b0 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 11 Feb 2019 17:13:12 +0100 Subject: [PATCH] Disallow calldata arrays with dynamically encoded base types in TypeChecker. --- libsolidity/analysis/TypeChecker.cpp | 10 ++++++++++ test/libsolidity/SolidityEndToEndTest.cpp | 16 ++++++++++++++++ test/libsolidity/syntaxTests/array/calldata.sol | 6 ++++++ .../syntaxTests/array/calldata_dynamic.sol | 6 ++++++ .../syntaxTests/array/calldata_multi.sol | 6 ++++++ .../syntaxTests/array/calldata_multi_dynamic.sol | 7 +++++++ .../syntaxTests/structs/array_calldata.sol | 1 + 7 files changed, 52 insertions(+) create mode 100644 test/libsolidity/syntaxTests/array/calldata.sol create mode 100644 test/libsolidity/syntaxTests/array/calldata_dynamic.sol create mode 100644 test/libsolidity/syntaxTests/array/calldata_multi.sol create mode 100644 test/libsolidity/syntaxTests/array/calldata_multi_dynamic.sol diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index e59195606..c716d6730 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -366,6 +366,16 @@ bool TypeChecker::visit(FunctionDefinition const& _function) for (ASTPointer const& var: _function.parameters()) { TypePointer baseType = type(*var); + if (auto const* arrayType = dynamic_cast(baseType.get())) + { + baseType = arrayType->baseType(); + if ( + !m_scope->isInterface() && + baseType->dataStoredIn(DataLocation::CallData) && + baseType->isDynamicallyEncoded() + ) + m_errorReporter.typeError(var->location(), "Calldata arrays with dynamically encoded base types are not yet supported."); + } while (auto const* arrayType = dynamic_cast(baseType.get())) baseType = arrayType->baseType(); diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 31d9be7a1..010a05d73 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -8013,6 +8013,22 @@ BOOST_AUTO_TEST_CASE(struct_named_constructor) ABI_CHECK(callContractFunction("s()"), encodeArgs(u256(1), true)); } +BOOST_AUTO_TEST_CASE(calldata_array) +{ + char const* sourceCode = R"( + pragma experimental ABIEncoderV2; + contract C { + function f(uint[2] calldata s) external pure returns (uint256 a, uint256 b) { + a = s[0]; + b = s[1]; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + + ABI_CHECK(callContractFunction("f(uint256[2])", encodeArgs(u256(42), u256(23))), encodeArgs(u256(42), u256(23))); +} + BOOST_AUTO_TEST_CASE(calldata_struct) { char const* sourceCode = R"( diff --git a/test/libsolidity/syntaxTests/array/calldata.sol b/test/libsolidity/syntaxTests/array/calldata.sol new file mode 100644 index 000000000..68276a8ec --- /dev/null +++ b/test/libsolidity/syntaxTests/array/calldata.sol @@ -0,0 +1,6 @@ +pragma experimental ABIEncoderV2; +contract Test { + function f(uint[3] calldata) external { } +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/array/calldata_dynamic.sol b/test/libsolidity/syntaxTests/array/calldata_dynamic.sol new file mode 100644 index 000000000..bba2541f9 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/calldata_dynamic.sol @@ -0,0 +1,6 @@ +pragma experimental ABIEncoderV2; +contract Test { + function f(uint[] calldata) external { } +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/array/calldata_multi.sol b/test/libsolidity/syntaxTests/array/calldata_multi.sol new file mode 100644 index 000000000..570f3e942 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/calldata_multi.sol @@ -0,0 +1,6 @@ +pragma experimental ABIEncoderV2; +contract Test { + function f(uint[3][4] calldata) external { } +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/array/calldata_multi_dynamic.sol b/test/libsolidity/syntaxTests/array/calldata_multi_dynamic.sol new file mode 100644 index 000000000..a732b4462 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/calldata_multi_dynamic.sol @@ -0,0 +1,7 @@ +pragma experimental ABIEncoderV2; +contract Test { + function f(uint[][] calldata) external { } +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError: (65-82): Calldata arrays with dynamically encoded base types are not yet supported. diff --git a/test/libsolidity/syntaxTests/structs/array_calldata.sol b/test/libsolidity/syntaxTests/structs/array_calldata.sol index 9e1071a0e..8da097884 100644 --- a/test/libsolidity/syntaxTests/structs/array_calldata.sol +++ b/test/libsolidity/syntaxTests/structs/array_calldata.sol @@ -6,3 +6,4 @@ contract Test { } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError: (131-145): Calldata arrays with dynamically encoded base types are not yet supported.