From 61e3f16b888dab4b74036e11aaf801b3458b63d6 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Thu, 22 Jun 2023 10:56:08 -0300 Subject: [PATCH] Disallow complex expressions as argument of abi.decode --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 18 +++++++++++++++++- ..._decode_with_tuple_of_other_than_types.sol | 2 +- .../abidecode/abi_decode_array_of_tuples.sol | 15 +++++++++++++++ .../abidecode/abi_decode_enum.sol | 8 ++++++++ ...invalid_argument_indexed_array_literal.sol | 7 +++++++ ..._argument_ternary_condition_expression.sol | 10 ++++++++++ ...abi_decode_invalid_argument_tuple_type.sol | 9 +++++++++ .../abidecode/abi_decode_member_acess.sol | 19 +++++++++++++++++++ 9 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_array_of_tuples.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_enum.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_indexed_array_literal.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_ternary_condition_expression.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_tuple_type.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_member_acess.sol diff --git a/Changelog.md b/Changelog.md index 7456a8a46e71..d35598268729 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Compiler Features: * SMTChecker: Add ``--model-checker-print-query`` CLI option and ``settings.modelChecker.printQuery`` JSON option to output the SMTChecker queries in the SMTLIB2 format. This requires using `smtlib2` solver only. * Standard JSON Interface: Add ``ast`` file-level output for Yul input. * Standard JSON Interface: Add ``irAst`` and ``irOptimizedAst`` contract-level outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR. + * Type Checker: Disallow complex expressions such ternary conditionals and nested tuples as arguments for ``abi.decode``. * Yul Optimizer: Stack-to-memory mover is now enabled by default whenever possible for via IR code generation and pure Yul compilation. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index e7721fd9e5b3..bc169491a4f5 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -249,7 +249,23 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c for (auto const& typeArgument: tupleExpression->components()) { solAssert(typeArgument, ""); - if (TypeType const* argTypeType = dynamic_cast(type(*typeArgument))) + if ( + !dynamic_cast(typeArgument.get()) && + !dynamic_cast(typeArgument.get()) && + !dynamic_cast(typeArgument.get()) && + !dynamic_cast(typeArgument.get()) + ) + { + + m_errorReporter.typeError( + 5901_error, + typeArgument->location(), + "Expression is not allowed as argument here. Argument must be " + "a built-in type name, an user-defined type name or an array of those." + ); + components.push_back(TypeProvider::emptyTuple()); + } + else if (TypeType const* argTypeType = dynamic_cast(type(*typeArgument))) { Type const* actualType = argTypeType->actualType(); solAssert(actualType, ""); diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/584_abi_decode_with_tuple_of_other_than_types.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/584_abi_decode_with_tuple_of_other_than_types.sol index 0d5fadcc808c..ce7ca9fcf72f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/584_abi_decode_with_tuple_of_other_than_types.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/584_abi_decode_with_tuple_of_other_than_types.sol @@ -2,4 +2,4 @@ contract C { function f() pure public { abi.decode("", (0)); } } // ---- -// TypeError 1039: (60-61): Argument has to be a type name. +// TypeError 5901: (60-61): Expression is not allowed as argument here. Argument must be a built-in type name, an user-defined type name or an array of those. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_array_of_tuples.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_array_of_tuples.sol new file mode 100644 index 000000000000..710f066a342f --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_array_of_tuples.sol @@ -0,0 +1,15 @@ +contract C { + function f() pure public { + abi.decode("", ((uint)[2])); + abi.decode("", ((uint)[])); + abi.decode("", ((uint)[][3])); + abi.decode("", ((uint)[4][])); + abi.decode("", ((uint)[5][6])); + } +} +// ---- +// Warning 6133: (52-79): Statement has no effect. +// Warning 6133: (89-115): Statement has no effect. +// Warning 6133: (125-154): Statement has no effect. +// Warning 6133: (164-193): Statement has no effect. +// Warning 6133: (203-233): Statement has no effect. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_enum.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_enum.sol new file mode 100644 index 000000000000..a44a65739291 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_enum.sol @@ -0,0 +1,8 @@ +contract C { + enum Color { red, green, blue } + function f() pure public { + abi.decode("", (Color)); + } +} +// ---- +// Warning 6133: (88-111): Statement has no effect. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_indexed_array_literal.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_indexed_array_literal.sol new file mode 100644 index 000000000000..1784296fc16a --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_indexed_array_literal.sol @@ -0,0 +1,7 @@ +contract C { + function f() pure public { + abi.decode("", ([uint][2])); + } +} +// ---- +// TypeError 9656: (68-74): Unable to deduce nameable type for array elements. Try adding explicit type conversion for the first element. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_ternary_condition_expression.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_ternary_condition_expression.sol new file mode 100644 index 000000000000..0a17f929a14a --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_ternary_condition_expression.sol @@ -0,0 +1,10 @@ +contract C { + function f() pure public { + int x; + abi.decode("", ((x = 1) > 0 ? int : int)); + abi.decode("", (true ? uint : uint)); + } +} +// ---- +// TypeError 5901: (83-106): Expression is not allowed as argument here. Argument must be a built-in type name, an user-defined type name or an array of those. +// TypeError 5901: (134-152): Expression is not allowed as argument here. Argument must be a built-in type name, an user-defined type name or an array of those. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_tuple_type.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_tuple_type.sol new file mode 100644 index 000000000000..0274c8ba0641 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_argument_tuple_type.sol @@ -0,0 +1,9 @@ +contract C { + function f() pure public { + abi.decode("", ((uint))); + abi.decode("", ((uint, int))); + } +} +// ---- +// TypeError 5901: (68-74): Expression is not allowed as argument here. Argument must be a built-in type name, an user-defined type name or an array of those. +// TypeError 5901: (102-113): Expression is not allowed as argument here. Argument must be a built-in type name, an user-defined type name or an array of those. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_member_acess.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_member_acess.sol new file mode 100644 index 000000000000..5078fcdebf3c --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_member_acess.sol @@ -0,0 +1,19 @@ +library L { + struct S { int a; } + enum State { idle, running, blocked } +} + +contract D { + struct X { uint b; } + enum Color { red, green, blue } +} + +contract C { + function f() pure public { + abi.decode("", (L.S)); + abi.decode("", (L.State)); + abi.decode("", (D.X)); + abi.decode("", (D.Color)); + } +} +// ----