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.
This commit is contained in:
Kamil Śliwak 2020-09-17 15:02:29 +02:00
parent 7a5957512c
commit 1a4cc4e64d
10 changed files with 81 additions and 2 deletions

View File

@ -18,6 +18,7 @@ Compiler Features:
Bugfixes: Bugfixes:
* Code generator: Fix internal error on stripping dynamic types from return parameters on EVM versions without ``RETURNDATACOPY``. * 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: Disallow ``virtual`` for modifiers in libraries.
* Type Checker: Correct the warning for homonymous, but not shadowing declarations. * Type Checker: Correct the warning for homonymous, but not shadowing declarations.
* ViewPureChecker: Prevent visibility check on constructors. * ViewPureChecker: Prevent visibility check on constructors.

View File

@ -404,10 +404,16 @@ TypePointer Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c
return encodingType; return encodingType;
TypePointer baseType = encodingType; TypePointer baseType = encodingType;
while (auto const* arrayType = dynamic_cast<ArrayType const*>(baseType)) while (auto const* arrayType = dynamic_cast<ArrayType const*>(baseType))
{
baseType = arrayType->baseType(); baseType = arrayType->baseType();
if (dynamic_cast<StructType const*>(baseType))
if (!_encoderV2) auto const* baseArrayType = dynamic_cast<ArrayType const*>(baseType);
if (!_encoderV2 && baseArrayType && baseArrayType->isDynamicallySized())
return nullptr; return nullptr;
}
if (!_encoderV2 && dynamic_cast<StructType const*>(baseType))
return nullptr;
return encodingType; return encodingType;
} }

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.