From d6d286b39bf0376b82602009806c687fb360fc01 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 8 Nov 2021 18:08:47 +0100 Subject: [PATCH] Disallow codecopy and codesize in pure functions. --- Changelog.md | 1 + docs/contracts/functions.rst | 1 + libevmasm/SemanticInformation.cpp | 2 ++ .../syntaxTests/inlineAssembly/hex_switch_case.sol | 2 +- .../inlineAssembly/string_literal_switch_case.sol | 2 +- test/libsolidity/syntaxTests/viewPureChecker/assembly.sol | 6 ++++++ 6 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 927d8f910..8392b5816 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ Breaking changes: * Disallow ``.pop()`` on arrays containing nested mappings. * Disallow ``delete`` on types that contain nested mappings. + * Disallow ``codecopy`` and ``codesize`` in ``pure`` functions. * Inline Assembly: Consider functions, function parameters and return variables for shadowing checks. * Commandline Interface: Remapping targets are not automatically added to allowed paths. * Commandline Interface: Assembler mode no longer enables all outputs by default. diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst index ff49e4f28..28eca096c 100644 --- a/docs/contracts/functions.rst +++ b/docs/contracts/functions.rst @@ -225,6 +225,7 @@ Functions can be declared ``pure`` in which case they promise not to read from o In particular, it should be possible to evaluate a ``pure`` function at compile-time given only its inputs and ``msg.data``, but without any knowledge of the current blockchain state. This means that reading from ``immutable`` variables can be a non-pure operation. +Similarly, the inline assembly builtins ``codecopy`` and ``codesize`` are not pure. .. note:: If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used, diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index 41dc07fcf..177208f0b 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -351,6 +351,8 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction) case Instruction::ORIGIN: case Instruction::CALLER: case Instruction::CALLVALUE: + case Instruction::CODESIZE: + case Instruction::CODECOPY: case Instruction::CHAINID: case Instruction::BASEFEE: case Instruction::GAS: diff --git a/test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol b/test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol index 038e8c4ff..7d63fa719 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/hex_switch_case.sol @@ -1,7 +1,7 @@ contract C { function f() public pure { assembly { - switch codesize() + switch calldatasize() case hex"00" {} case hex"1122" {} } diff --git a/test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol b/test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol index 0a63987e1..1773d817b 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/string_literal_switch_case.sol @@ -1,7 +1,7 @@ contract C { function f() public pure { assembly { - switch codesize() + switch calldatasize() case "1" {} case "2" {} } diff --git a/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol b/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol index 0926d2e14..a038885e6 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol @@ -26,5 +26,11 @@ contract C { function l() public view { assembly { pop(extcodesize(0)) } } + function m() public view { + assembly { codecopy(0,0,0) } + } + function n() public view { + assembly { pop(codesize()) } + } } // ----