From cdaba011ba02a38e7321a118279f7f320a3b4b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20S=C3=A1?= Date: Thu, 25 Jan 2018 01:43:48 +0000 Subject: [PATCH] v0.0.5 - Critical fix to the `slice()` method (#14) * Adding test to account for #13 * Fix for #13 Multiples of 32 bytes can now be safely sliced * More tests for #13 * Bump version to v0.0.5 --- contracts/BytesLib.sol | 10 ++++++++-- ethpm.json | 2 +- package.json | 2 +- test/TestBytesLib2.sol | 20 ++++++++++++++------ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/contracts/BytesLib.sol b/contracts/BytesLib.sol index 4470f4b..d7bd7c4 100755 --- a/contracts/BytesLib.sol +++ b/contracts/BytesLib.sol @@ -232,11 +232,17 @@ library BytesLib { // the actual length of the slice. let lengthmod := and(_length, 31) - let mc := add(tempBytes, lengthmod) + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { - let cc := add(add(_bytes, lengthmod), _start) + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) diff --git a/ethpm.json b/ethpm.json index 27e7da2..6333306 100644 --- a/ethpm.json +++ b/ethpm.json @@ -1,6 +1,6 @@ { "package_name": "bytes", - "version": "0.0.4", + "version": "0.0.5", "description": "Solidity bytes tightly packed arrays utility library.", "authors": [ "Gonçalo Sá " diff --git a/package.json b/package.json index 04ad7d5..d8bc40e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "solidity-bytes-utils", - "version": "0.0.4", + "version": "0.0.5", "description": "Solidity bytes tightly packed arrays utility library.", "main": "truffle.js", "repository": { diff --git a/test/TestBytesLib2.sol b/test/TestBytesLib2.sol index 9528a55..2a82642 100755 --- a/test/TestBytesLib2.sol +++ b/test/TestBytesLib2.sol @@ -54,30 +54,38 @@ contract TestBytesLib2 { */ function testSlice() public { - bytes memory memBytes33 = hex"f00d0000000000000000000000000000000000000000000000000000000000feed"; + bytes memory memBytes = hex"f00d0000000000000000000000000000000000000000000000000000000000feedf00d00000000000000000000000000000000000000000000000000000000feed"; bytes memory testBytes; bytes memory resultBytes; testBytes = hex"f00d"; - resultBytes = memBytes33.slice(0,2); + resultBytes = memBytes.slice(0,2); AssertBytes.equal(resultBytes, testBytes, "Normal slicing array failed."); testBytes = hex""; - resultBytes = memBytes33.slice(1,0); + resultBytes = memBytes.slice(1,0); AssertBytes.equal(resultBytes, testBytes, "Slicing with zero-length failed."); testBytes = hex""; - resultBytes = memBytes33.slice(0,0); + resultBytes = memBytes.slice(0,0); AssertBytes.equal(resultBytes, testBytes, "Slicing with zero-length on index 0 failed."); testBytes = hex"feed"; - resultBytes = memBytes33.slice(31,2); + resultBytes = memBytes.slice(31,2); AssertBytes.equal(resultBytes, testBytes, "Slicing across the 32-byte slot boundary failed."); testBytes = hex"f00d0000000000000000000000000000000000000000000000000000000000feed"; - resultBytes = memBytes33.slice(0,33); + resultBytes = memBytes.slice(0,33); AssertBytes.equal(resultBytes, testBytes, "Full length slice failed."); + + testBytes = hex"f00d0000000000000000000000000000000000000000000000000000000000fe"; + resultBytes = memBytes.slice(0,32); + AssertBytes.equal(resultBytes, testBytes, "Multiple of 32 bytes slice failed."); + + testBytes = hex"f00d0000000000000000000000000000000000000000000000000000000000feedf00d00000000000000000000000000000000000000000000000000000000fe"; + resultBytes = memBytes.slice(0,64); + AssertBytes.equal(resultBytes, testBytes, "Multiple (*2) of 32 bytes slice failed."); // Now we're going to test for slicing actions that throw present in the functions below // with a ThrowProxy contract