From 1a4cc4e64d028fd5edcd87c77a0649fe983452da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 17 Sep 2020 15:02:29 +0200 Subject: [PATCH] Fix type check for nested arrays in abi.encode/decode functions in ABIEncoderV1 - Without this fix, nested arrays are not detected as unsupported and compiler fails on an UnimplementedError. - Now it's consistent with how structs are handled in ABIEncoderV1. --- Changelog.md | 1 + libsolidity/ast/Types.cpp | 10 ++++++++-- .../abi_encodePacked_nested_dynamic_array.sol | 7 +++++++ .../abi_encodePacked_nested_dynamic_array_v2.sol | 9 +++++++++ .../abi_encode_nested_dynamic_array.sol | 7 +++++++ .../abi_encode_nested_dynamic_array_v2.sol | 9 +++++++++ .../abidecode/abi_decode_nested_dynamic_array.sol | 7 +++++++ .../abi_decode_nested_dynamic_array_v2.sol | 9 +++++++++ .../abidecode/abi_decode_struct.sol | 11 +++++++++++ .../abidecode/abi_decode_struct_v2.sol | 13 +++++++++++++ 10 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array_v2.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array_v2.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array_v2.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct_v2.sol diff --git a/Changelog.md b/Changelog.md index 33f2c2ef5..7716edd93 100644 --- a/Changelog.md +++ b/Changelog.md @@ -18,6 +18,7 @@ Compiler Features: Bugfixes: * Code generator: Fix internal error on stripping dynamic types from return parameters on EVM versions without ``RETURNDATACOPY``. + * Type Checker: Add missing check against nested dynamic arrays in ABI encoding functions when ABIEncoderV2 is disabled. * Type Checker: Disallow ``virtual`` for modifiers in libraries. * Type Checker: Correct the warning for homonymous, but not shadowing declarations. * ViewPureChecker: Prevent visibility check on constructors. diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index b0418dee5..070bcb483 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -404,10 +404,16 @@ TypePointer Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c return encodingType; TypePointer baseType = encodingType; while (auto const* arrayType = dynamic_cast(baseType)) + { baseType = arrayType->baseType(); - if (dynamic_cast(baseType)) - if (!_encoderV2) + + auto const* baseArrayType = dynamic_cast(baseType); + if (!_encoderV2 && baseArrayType && baseArrayType->isDynamicallySized()) return nullptr; + } + if (!_encoderV2 && dynamic_cast(baseType)) + return nullptr; + return encodingType; } diff --git a/test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array.sol b/test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array.sol new file mode 100644 index 000000000..3645cf592 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + abi.encodePacked([new uint[](5), new uint[](7)]); + } +} +// ---- +// TypeError 9578: (69-99): Type not supported in packed mode. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array_v2.sol b/test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array_v2.sol new file mode 100644 index 000000000..54a81e839 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abi_encodePacked_nested_dynamic_array_v2.sol @@ -0,0 +1,9 @@ +pragma experimental ABIEncoderV2; + +contract C { + function f() public pure { + abi.encodePacked([new uint[](5), new uint[](7)]); + } +} +// ---- +// TypeError 9578: (104-134): Type not supported in packed mode. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array.sol b/test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array.sol new file mode 100644 index 000000000..e4e5a85dc --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array.sol @@ -0,0 +1,7 @@ +contract C { + function test() public pure { + abi.encode([new uint[](5), new uint[](7)]); + } +} +// ---- +// TypeError 2056: (66-96): This type cannot be encoded. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array_v2.sol b/test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array_v2.sol new file mode 100644 index 000000000..911c7b6fd --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abi_encode_nested_dynamic_array_v2.sol @@ -0,0 +1,9 @@ +pragma experimental ABIEncoderV2; + +contract C { + function f() public pure { + abi.encode([new uint[](5), new uint[](7)]); + } +} +// ---- +// Warning 6133: (87-129): Statement has no effect. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array.sol new file mode 100644 index 000000000..d1820aab1 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + abi.decode("1234", (uint[][3])); + } +} +// ---- +// TypeError 9611: (72-81): Decoding type uint256[] memory[3] memory not supported. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array_v2.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array_v2.sol new file mode 100644 index 000000000..55f3b169b --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_nested_dynamic_array_v2.sol @@ -0,0 +1,9 @@ +pragma experimental ABIEncoderV2; + +contract C { + function f() public pure { + abi.decode("1234", (uint[][3])); + } +} +// ---- +// Warning 6133: (87-118): Statement has no effect. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct.sol new file mode 100644 index 000000000..b8b49ccdb --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct.sol @@ -0,0 +1,11 @@ +struct S { + uint x; +} + +contract C { + function f() public pure { + abi.decode("1234", (S)); + } +} +// ---- +// TypeError 9611: (98-99): Decoding type struct S memory not supported. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct_v2.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct_v2.sol new file mode 100644 index 000000000..80c9c527a --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_struct_v2.sol @@ -0,0 +1,13 @@ +pragma experimental ABIEncoderV2; + +struct S { + uint x; +} + +contract C { + function f() public pure { + abi.decode("1234", (S)); + } +} +// ---- +// Warning 6133: (113-136): Statement has no effect.