Skip to content

Commit

Permalink
Disallow complex expressions as argument of abi.decode
Browse files Browse the repository at this point in the history
  • Loading branch information
matheusaaguiar committed Jun 22, 2023
1 parent b26090c commit 61e3f16
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.


Expand Down
18 changes: 17 additions & 1 deletion libsolidity/analysis/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,23 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c
for (auto const& typeArgument: tupleExpression->components())
{
solAssert(typeArgument, "");
if (TypeType const* argTypeType = dynamic_cast<TypeType const*>(type(*typeArgument)))
if (
!dynamic_cast<ElementaryTypeNameExpression const*>(typeArgument.get()) &&
!dynamic_cast<Identifier const*>(typeArgument.get()) &&
!dynamic_cast<IndexAccess const*>(typeArgument.get()) &&
!dynamic_cast<MemberAccess const*>(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<TypeType const*>(type(*typeArgument)))
{
Type const* actualType = argTypeType->actualType();
solAssert(actualType, "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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));
}
}
// ----

0 comments on commit 61e3f16

Please sign in to comment.