From 5072472917d587d0f18cc5c4ab193aa6fd29ec51 Mon Sep 17 00:00:00 2001 From: Duc Thanh Nguyen Date: Sun, 17 Jul 2022 01:00:12 -0400 Subject: [PATCH] Fix abi.encodeCall checks --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 42 +++++++++++++------ .../abi_encodeCall_error_free_function.sol | 7 ++++ .../abi_encodeCall_event_free_function.sol | 9 ++++ .../abiEncoder/abi_encodeCall_free_func.sol | 7 ++++ ...bi_encodeCall_on_lib_func_in_free_func.sol | 9 ++++ 6 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_error_free_function.sol create mode 100644 test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_event_free_function.sol create mode 100644 test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_free_func.sol create mode 100644 test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_on_lib_func_in_free_func.sol diff --git a/Changelog.md b/Changelog.md index 09be3d9e9..a39c1cabd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Compiler Features: Bugfixes: * Commandline Interface: Disallow the following options outside of the compiler mode: ``--via-ir``,``--metadata-literal``, ``--metadata-hash``, ``--model-checker-show-unproved``, ``--model-checker-div-mod-no-slacks``, ``--model-checker-engine``, ``--model-checker-invariants``, ``--model-checker-solvers``, ``--model-checker-timeout``, ``--model-checker-contracts``, ``--model-checker-targets``. + * Type Checker: Fix null dereference in `abi.encodeCall` type checking of free function. ### 0.8.15 (2022-06-15) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 90359c459..e2c8c52f7 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2195,14 +2195,28 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa ) { string msg = "Expected regular external function type, or external view on public function."; - if (externalFunctionType->kind() == FunctionType::Kind::Internal) - msg += " Provided internal function."; - else if (externalFunctionType->kind() == FunctionType::Kind::DelegateCall) - msg += " Cannot use library functions for abi.encodeCall."; - else if (externalFunctionType->kind() == FunctionType::Kind::Creation) - msg += " Provided creation function."; - else - msg += " Cannot use special function."; + + switch (externalFunctionType->kind()) + { + case FunctionType::Kind::Internal: + msg += " Provided internal function."; + break; + case FunctionType::Kind::DelegateCall: + msg += " Cannot use library functions for abi.encodeCall."; + break; + case FunctionType::Kind::Creation: + msg += " Provided creation function."; + break; + case FunctionType::Kind::Event: + msg += " Cannot use events for abi.encodeCall."; + break; + case FunctionType::Kind::Error: + msg += " Cannot use errors for abi.encodeCall."; + break; + default: + msg += " Cannot use special function."; + } + SecondarySourceLocation ssl{}; if (externalFunctionType->hasDeclaration()) @@ -2213,10 +2227,14 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa externalFunctionType->declaration().scope() == m_currentContract ) msg += " Did you forget to prefix \"this.\"?"; - else if (util::contains( - m_currentContract->annotation().linearizedBaseContracts, - externalFunctionType->declaration().scope() - ) && externalFunctionType->declaration().scope() != m_currentContract) + else if ( + m_currentContract && + externalFunctionType->declaration().scope() != m_currentContract && + util::contains( + m_currentContract->annotation().linearizedBaseContracts, + externalFunctionType->declaration().scope() + ) + ) msg += " Functions from base contracts have to be external."; } diff --git a/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_error_free_function.sol b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_error_free_function.sol new file mode 100644 index 000000000..c59b1b3f7 --- /dev/null +++ b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_error_free_function.sol @@ -0,0 +1,7 @@ +error E(uint); + +function f() { + abi.encodeCall(E, (1)); +} +// ---- +// TypeError 3509: (50-51): Expected regular external function type, or external view on public function. Cannot use errors for abi.encodeCall. diff --git a/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_event_free_function.sol b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_event_free_function.sol new file mode 100644 index 000000000..39930125b --- /dev/null +++ b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_event_free_function.sol @@ -0,0 +1,9 @@ +library L { + event E(uint); +} + +function f() { + abi.encodeCall(L.E, (1)); +} +// ---- +// TypeError 3509: (68-71): Expected regular external function type, or external view on public function. Cannot use events for abi.encodeCall. diff --git a/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_free_func.sol b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_free_func.sol new file mode 100644 index 000000000..5567810f4 --- /dev/null +++ b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_free_func.sol @@ -0,0 +1,7 @@ +function g(uint) {} + +function f() { + abi.encodeCall(g, (1)); +} +// ---- +// TypeError 3509: (55-56): Expected regular external function type, or external view on public function. Provided internal function. diff --git a/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_on_lib_func_in_free_func.sol b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_on_lib_func_in_free_func.sol new file mode 100644 index 000000000..ed2e02a11 --- /dev/null +++ b/test/libsolidity/syntaxTests/abiEncoder/abi_encodeCall_on_lib_func_in_free_func.sol @@ -0,0 +1,9 @@ +library L { + function g() external {} +} + +function f() { + abi.encodeCall(L.g, (1)); +} +// ---- +// TypeError 3509: (78-81): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall.