@@ -39,26 +39,32 @@ library Base64 {
3939 let tablePtr := add (table, 1 )
4040
4141 // Prepare result pointer, jump over length
42- let resultPtr := add (result, 32 )
42+ let resultPtr := add (result, 0x20 )
43+ let dataPtr := data
44+ let endPtr := add (data, mload (data))
45+
46+ // In some cases, the last iteration will read bytes after the end of the data. We cache the value, and
47+ // set it to zero to make sure no dirty bytes are read in that section.
48+ let afterPtr := add (endPtr, 0x20 )
49+ let afterCache := mload (afterPtr)
50+ mstore (afterPtr, 0x00 )
4351
4452 // Run over the input, 3 bytes at a time
4553 for {
46- let dataPtr := data
47- let endPtr := add (data, mload (data))
54+
4855 } lt (dataPtr, endPtr) {
4956
5057 } {
5158 // Advance 3 bytes
5259 dataPtr := add (dataPtr, 3 )
5360 let input := mload (dataPtr)
5461
55- // To write each character, shift the 3 bytes (18 bits) chunk
62+ // To write each character, shift the 3 byte (24 bits) chunk
5663 // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
57- // and apply logical AND with 0x3F which is the number of
58- // the previous character in the ASCII table prior to the Base64 Table
59- // The result is then added to the table to get the character to write,
60- // and finally write it in the result pointer but with a left shift
61- // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits
64+ // and apply logical AND with 0x3F to bitmask the least significant 6 bits.
65+ // Use this as an index into the lookup table, mload an entire word
66+ // so the desired character is in the least significant byte, and
67+ // mstore8 this least significant byte into the result and continue.
6268
6369 mstore8 (resultPtr, mload (add (tablePtr, and (shr (18 , input), 0x3F ))))
6470 resultPtr := add (resultPtr, 1 ) // Advance
@@ -73,6 +79,9 @@ library Base64 {
7379 resultPtr := add (resultPtr, 1 ) // Advance
7480 }
7581
82+ // Reset the value that was cached
83+ mstore (afterPtr, afterCache)
84+
7685 // When data `bytes` is not exactly 3 bytes long
7786 // it is padded with `=` characters at the end
7887 switch mod (mload (data), 3 )
0 commit comments