From 3a4233f3ad05b1224de4e3db2bebb50b3ffbdaa4 Mon Sep 17 00:00:00 2001 From: Djordje Mijovic Date: Mon, 19 Apr 2021 16:35:21 +0200 Subject: [PATCH] [Sol->Yul] Adding bounds check when increasing size of byte array. --- libsolidity/codegen/YulUtilFunctions.cpp | 80 +++++++++---------- .../array/push/push_no_args_bytes.sol | 2 +- 2 files changed, 39 insertions(+), 43 deletions(-) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 03a99bef5..1f0889e59 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -1209,31 +1209,24 @@ std::string YulUtilFunctions::resizeArrayFunction(ArrayType const& _type) string YulUtilFunctions::resizeDynamicByteArrayFunction(ArrayType const& _type) { string functionName = "resize_array_" + _type.identifier(); - return m_functionCollector.createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&](vector& _args, vector&) { + _args = {"array", "newLen"}; return Whiskers(R"( - function (array, newLen) { - if gt(newLen, ) { - () - } + let data := sload(array) + let oldLen := (data) - let data := sload(array) - let oldLen := (data) + if gt(newLen, oldLen) { + (array, data, oldLen, newLen) + } - if gt(newLen, oldLen) { - (array, data, oldLen, newLen) - } - - if lt(newLen, oldLen) { - (array, data, oldLen, newLen) - } - })") - ("functionName", functionName) - ("panic", panicFunction(PanicCode::ResourceError)) - ("extractLength", extractByteArrayLengthFunction()) - ("maxArrayLength", (u256(1) << 64).str()) - ("decreaseSize", decreaseByteArraySizeFunction(_type)) - ("increaseSize", increaseByteArraySizeFunction(_type)) - .render(); + if lt(newLen, oldLen) { + (array, data, oldLen, newLen) + } + )") + ("extractLength", extractByteArrayLengthFunction()) + ("decreaseSize", decreaseByteArraySizeFunction(_type)) + ("increaseSize", increaseByteArraySizeFunction(_type)) + .render(); }); } @@ -1282,32 +1275,35 @@ string YulUtilFunctions::decreaseByteArraySizeFunction(ArrayType const& _type) string YulUtilFunctions::increaseByteArraySizeFunction(ArrayType const& _type) { string functionName = "byte_array_increase_size_" + _type.identifier(); - return m_functionCollector.createFunction(functionName, [&]() { + return m_functionCollector.createFunction(functionName, [&](vector& _args, vector&) { + _args = {"array", "data", "oldLen", "newLen"}; return Whiskers(R"( - function (array, data, oldLen, newLen) { - switch lt(oldLen, 32) + if gt(newLen, ) { () } + + switch lt(oldLen, 32) + case 0 { + // in this case array stays unpacked, so we just set new length + sstore(array, add(mul(2, newLen), 1)) + } + default { + switch lt(newLen, 32) case 0 { - // in this case array stays unpacked, so we just set new length + // we need to copy elements to data area as we changed array from packed to unpacked + data := and(not(0xff), data) + sstore((array), data) sstore(array, add(mul(2, newLen), 1)) } default { - switch lt(newLen, 32) - case 0 { - // we need to copy elements to data area as we changed array from packed to unpacked - data := and(not(0xff), data) - sstore((array), data) - sstore(array, add(mul(2, newLen), 1)) - } - default { - // here array stays packed, we just need to increase length - sstore(array, (data, newLen)) - } + // here array stays packed, we just need to increase length + sstore(array, (data, newLen)) } - })") - ("functionName", functionName) - ("dataPosition", arrayDataAreaFunction(_type)) - ("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction()) - .render(); + } + )") + ("panic", panicFunction(PanicCode::ResourceError)) + ("maxArrayLength", (u256(1) << 64).str()) + ("dataPosition", arrayDataAreaFunction(_type)) + ("encodeUsedSetLen", shortByteArrayEncodeUsedAreaSetLengthFunction()) + .render(); }); } diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol index fb859941d..088c4bddd 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol @@ -23,7 +23,7 @@ contract C { // ---- // l() -> 0 // g(uint256): 70 -> -// gas irOptimized: 429679 +// gas irOptimized: 434229 // gas legacy: 419791 // gas legacyOptimized: 415408 // l() -> 70