diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 474848760cef..e558be35957a 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -242,7 +242,6 @@ std::string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMem } )"); elementTempl("dynamic", decodingTypes[i]->isDynamicallyEncoded()); - // TODO add test elementTempl("revertString", revertReasonIfDebugFunction("ABI decoding: invalid tuple offset")); elementTempl("load", _fromMemory ? "mload" : "calldataload"); elementTempl("values", boost::algorithm::join(valueNamesLocal, ", ")); diff --git a/test/libsolidity/ABIDecoderTests.cpp b/test/libsolidity/ABIDecoderTests.cpp index e8ffcad27eb8..08dfcd529bd4 100644 --- a/test/libsolidity/ABIDecoderTests.cpp +++ b/test/libsolidity/ABIDecoderTests.cpp @@ -426,6 +426,24 @@ BOOST_AUTO_TEST_CASE(complex_struct) ) } +BOOST_AUTO_TEST_CASE(invalid_tuple_offset) +{ + std::string sourceCode = R"( + contract C { + function f(uint[] calldata x) external pure returns (uint) { + return x.length > 0 ? x[0] : 0; + } + } + )"; + BOTH_ENCODERS( + compileAndRun(sourceCode); + // Creating an invalid call with array offset pointing outside the calldata + bytes calldata = encodeArgs(0x20, 0xffff) + bytes(62, 0); // 0xffff is an invalid offset + // This should revert because the array offset is invalid + ABI_CHECK(callContractFunctionNoEncoding("f(uint256[])", calldata), encodeArgs()); + ) +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces