From c16b5358042ea704237710825e5b2c361446f65c Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 3 Nov 2020 13:27:18 +0100 Subject: [PATCH] Validate external functions from calldata. --- libsolidity/codegen/YulUtilFunctions.cpp | 55 +++++++++++-------- .../abiEncoderV2/cleanup/function.sol | 2 + 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index b28fc0fe7..9b80c5e7d 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -3553,37 +3553,44 @@ string YulUtilFunctions::readFromMemoryOrCalldata(Type const& _type, bool _fromC } solAssert(_type.isValueType(), ""); - if (auto const* funType = dynamic_cast(&_type)) - if (funType->kind() == FunctionType::Kind::External) - return Whiskers(R"( - function (memPtr) -> addr, selector { - let combined := (memPtr) - addr, selector := (combined) - } - )") - ("functionName", functionName) - ("load", _fromCalldata ? "calldataload" : "mload") - ("splitFunction", splitExternalFunctionIdFunction()) - .render(); - - - return Whiskers(R"( - function (ptr) -> value { + Whiskers templ(R"( + function (ptr) -> { - value := calldataload(ptr) + let value := calldataload(ptr) (value) - value := (mload(ptr)) + let value := (mload(ptr)) + + := + + (value) + + value + } - )") - ("functionName", functionName) - ("fromCalldata", _fromCalldata) - ("validate", validatorFunction(_type, true)) + )"); + templ("functionName", functionName); + templ("fromCalldata", _fromCalldata); + if (_fromCalldata) + templ("validate", validatorFunction(_type, true)); + auto const* funType = dynamic_cast(&_type); + if (funType && funType->kind() == FunctionType::Kind::External) + { + templ("externalFunction", true); + templ("splitFunction", splitExternalFunctionIdFunction()); + templ("returnVariables", "addr, selector"); + } + else + { + templ("externalFunction", false); + templ("returnVariables", "returnValue"); + } + // Byte array elements generally need cleanup. // Other types are cleaned as well to account for dirty memory e.g. due to inline assembly. - ("cleanup", cleanupFunction(_type)) - .render(); + templ("cleanup", cleanupFunction(_type)); + return templ.render(); }); } diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/function.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/function.sol index 3221bb573..b872b2fb1 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/function.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/function.sol @@ -16,6 +16,8 @@ contract C { return (this.ggg(s.f), this.h(s)); } } +// ==== +// compileViaYul: also // ---- // ffff(uint256): 0 -> 0, 0 // ggg(function): 0 -> 0