@@ -15,7 +15,11 @@ library BytesLib {
15
15
bytes memory _bytes ,
16
16
uint256 _start ,
17
17
uint256 _length
18
- ) internal pure returns (bytes memory ) {
18
+ )
19
+ internal
20
+ pure
21
+ returns (bytes memory )
22
+ {
19
23
require (_length + 31 >= _length, "slice_overflow " );
20
24
require (_start + _length >= _start, "slice_overflow " );
21
25
require (_bytes.length >= _start + _length, "slice_outOfBounds " );
@@ -24,57 +28,54 @@ library BytesLib {
24
28
25
29
assembly {
26
30
switch iszero (_length)
27
- case 0 {
28
- // Get a location of some free memory and store it in tempBytes as
29
- // Solidity does for memory variables.
30
- tempBytes := mload (0x40 )
31
+ case 0 {
32
+ // Get a location of some free memory and store it in tempBytes as
33
+ // Solidity does for memory variables.
34
+ tempBytes := mload (0x40 )
31
35
32
- // The first word of the slice result is potentially a partial
33
- // word read from the original array. To read it, we calculate
34
- // the length of that partial word and start copying that many
35
- // bytes into the array. The first word we copy will start with
36
- // data we don't care about, but the last `lengthmod` bytes will
37
- // land at the beginning of the contents of the new array. When
38
- // we're done copying, we overwrite the full first word with
39
- // the actual length of the slice.
40
- let lengthmod := and (_length, 31 )
36
+ // The first word of the slice result is potentially a partial
37
+ // word read from the original array. To read it, we calculate
38
+ // the length of that partial word and start copying that many
39
+ // bytes into the array. The first word we copy will start with
40
+ // data we don't care about, but the last `lengthmod` bytes will
41
+ // land at the beginning of the contents of the new array. When
42
+ // we're done copying, we overwrite the full first word with
43
+ // the actual length of the slice.
44
+ let lengthmod := and (_length, 31 )
41
45
42
- // The multiplication in the next line is necessary
43
- // because when slicing multiples of 32 bytes (lengthmod == 0)
44
- // the following copy loop was copying the origin's length
45
- // and then ending prematurely not copying everything it should.
46
- let mc := add (add (tempBytes, lengthmod), mul (0x20 , iszero (lengthmod)))
47
- let end := add (mc, _length)
46
+ // The multiplication in the next line is necessary
47
+ // because when slicing multiples of 32 bytes (lengthmod == 0)
48
+ // the following copy loop was copying the origin's length
49
+ // and then ending prematurely not copying everything it should.
50
+ let mc := add (add (tempBytes, lengthmod), mul (0x20 , iszero (lengthmod)))
51
+ let end := add (mc, _length)
48
52
49
- for {
50
- // The multiplication in the next line has the same exact purpose
51
- // as the one above.
52
- let cc := add (
53
- add (add (_bytes, lengthmod), mul (0x20 , iszero (lengthmod))),
54
- _start
55
- )
56
- } lt (mc, end) {
57
- mc := add (mc, 0x20 )
58
- cc := add (cc, 0x20 )
59
- } {
60
- mstore (mc, mload (cc))
61
- }
53
+ for {
54
+ // The multiplication in the next line has the same exact purpose
55
+ // as the one above.
56
+ let cc := add (add (add (_bytes, lengthmod), mul (0x20 , iszero (lengthmod))), _start)
57
+ } lt (mc, end) {
58
+ mc := add (mc, 0x20 )
59
+ cc := add (cc, 0x20 )
60
+ } {
61
+ mstore (mc, mload (cc))
62
+ }
62
63
63
- mstore (tempBytes, _length)
64
+ mstore (tempBytes, _length)
64
65
65
- //update free-memory pointer
66
- //allocating the array padded to 32 bytes like the compiler does now
67
- mstore (0x40 , and (add (mc, 31 ), not (31 )))
68
- }
69
- //if we want a zero-length slice let's just return a zero-length array
70
- default {
71
- tempBytes := mload (0x40 )
72
- //zero out the 32 bytes slice we are about to return
73
- //we need to do it because Solidity does not garbage collect
74
- mstore (tempBytes, 0 )
66
+ //update free-memory pointer
67
+ //allocating the array padded to 32 bytes like the compiler does now
68
+ mstore (0x40 , and (add (mc, 31 ), not (31 )))
69
+ }
70
+ //if we want a zero-length slice let's just return a zero-length array
71
+ default {
72
+ tempBytes := mload (0x40 )
73
+ //zero out the 32 bytes slice we are about to return
74
+ //we need to do it because Solidity does not garbage collect
75
+ mstore (tempBytes, 0 )
75
76
76
- mstore (0x40 , add (tempBytes, 0x20 ))
77
- }
77
+ mstore (0x40 , add (tempBytes, 0x20 ))
78
+ }
78
79
}
79
80
80
81
return tempBytes;
0 commit comments