@@ -11,6 +11,8 @@ import {SafeCast} from "./math/SafeCast.sol";
11
11
library Base64 {
12
12
using SafeCast for bool ;
13
13
14
+ error InvalidBase64Digit (uint8 );
15
+
14
16
/**
15
17
* @dev Converts a `bytes` to its Bytes64 `string` representation.
16
18
*/
@@ -141,6 +143,8 @@ library Base64 {
141
143
* @dev Internal decoding
142
144
*/
143
145
function _decode (bytes memory data ) private pure returns (bytes memory result ) {
146
+ bytes4 errorSelector = InvalidBase64Digit.selector ;
147
+
144
148
uint256 dataLength = data.length ;
145
149
if (dataLength == 0 ) return "" ;
146
150
@@ -161,17 +165,6 @@ library Base64 {
161
165
mstore (0x20 , 0x0a0b0c0d0e0f10111213141516171819ffffffff3fff1a1b1c1d1e1f20212223 )
162
166
mstore (0x00 , 0x3eff3eff3f3435363738393a3b3c3dffffff00ffffff00010203040506070809 )
163
167
164
- // decode function
165
- function decodeChr (chr) -> decoded {
166
- if or (lt (chr, 43 ), gt (chr, 122 )) {
167
- revert (0 , 0 )
168
- }
169
- decoded := byte (0 , mload (sub (chr, 43 )))
170
- if gt (decoded, 63 ) {
171
- revert (0 , 0 )
172
- }
173
- }
174
-
175
168
// Prepare result pointer, jump over length
176
169
let dataPtr := data
177
170
let resultPtr := add (result, 0x20 )
@@ -191,11 +184,36 @@ library Base64 {
191
184
let input := mload (dataPtr)
192
185
193
186
// Decode each byte in the chunk as a 6 bit block, and align them to form a block of 3 bytes
187
+ let a := sub (byte (28 , input), 43 )
188
+ if iszero (and (shl (a, 1 ), 0xffffffd0ffffffc47ff5 )) {
189
+ mstore (0 , errorSelector)
190
+ mstore (4 , add (a, 49 ))
191
+ revert (0 , 0x24 )
192
+ }
193
+ let b := sub (byte (29 , input), 43 )
194
+ if iszero (and (shl (b, 1 ), 0xffffffd0ffffffc47ff5 )) {
195
+ mstore (0 , errorSelector)
196
+ mstore (4 , add (b, 49 ))
197
+ revert (0 , 0x24 )
198
+ }
199
+ let c := sub (byte (30 , input), 43 )
200
+ if iszero (and (shl (c, 1 ), 0xffffffd0ffffffc47ff5 )) {
201
+ mstore (0 , errorSelector)
202
+ mstore (4 , add (c, 49 ))
203
+ revert (0 , 0x24 )
204
+ }
205
+ let d := sub (byte (31 , input), 43 )
206
+ if iszero (and (shl (d, 1 ), 0xffffffd0ffffffc47ff5 )) {
207
+ mstore (0 , errorSelector)
208
+ mstore (4 , add (d, 49 ))
209
+ revert (0 , 0x24 )
210
+ }
211
+
194
212
mstore (
195
213
resultPtr,
196
214
or (
197
- or (shl (250 , decodeChr ( byte (28 , input ))), shl (244 , decodeChr ( byte (29 , input )))),
198
- or (shl (238 , decodeChr ( byte (30 , input ))), shl (232 , decodeChr ( byte (31 , input ))))
215
+ or (shl (250 , byte (0 , mload (a ))), shl (244 , byte (0 , mload (b )))),
216
+ or (shl (238 , byte (0 , mload (c ))), shl (232 , byte (0 , mload (d ))))
199
217
)
200
218
)
201
219
0 commit comments