23
23
24
24
const {
25
25
Array,
26
- ArrayFrom,
27
26
ArrayIsArray,
28
27
ArrayPrototypeForEach,
29
- ArrayPrototypeIndexOf,
30
28
MathFloor,
31
29
MathMin,
32
30
MathTrunc,
@@ -1255,35 +1253,41 @@ function btoa(input) {
1255
1253
throw new ERR_MISSING_ARGS ( 'input' ) ;
1256
1254
}
1257
1255
input = `${ input } ` ;
1256
+ let acc = 0 ;
1258
1257
for ( let n = 0 ; n < input . length ; n ++ ) {
1259
- if ( input [ n ] . charCodeAt ( 0 ) > 0xff )
1260
- throw lazyDOMException ( 'Invalid character' , 'InvalidCharacterError' ) ;
1258
+ acc |= StringPrototypeCharCodeAt ( input , n ) ;
1259
+ }
1260
+ if ( acc & ~ 0xff ) {
1261
+ throw lazyDOMException ( 'Invalid character' , 'InvalidCharacterError' ) ;
1261
1262
}
1262
1263
const buf = Buffer . from ( input , 'latin1' ) ;
1263
1264
return buf . toString ( 'base64' ) ;
1264
1265
}
1265
1266
1266
1267
// Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode
1268
+ // https://infra.spec.whatwg.org/#ascii-whitespace
1269
+ // Valid Characters: [\t\n\f\r +/0-9=A-Za-z]
1270
+ // Lookup table (-1 = invalid, 0 = valid)
1271
+ /* eslint-disable no-multi-spaces, indent */
1267
1272
const kForgivingBase64AllowedChars = [
1268
- // ASCII whitespace
1269
- // Refs: https://infra.spec.whatwg.org/#ascii-whitespace
1270
- 0x09 , 0x0A , 0x0C , 0x0D , 0x20 ,
1271
-
1272
- // Uppercase letters
1273
- ... ArrayFrom ( { length : 26 } , ( _ , i ) => StringPrototypeCharCodeAt ( 'A' ) + i ) ,
1274
-
1275
- // Lowercase letters
1276
- ... ArrayFrom ( { length : 26 } , ( _ , i ) => StringPrototypeCharCodeAt ( 'a' ) + i ) ,
1277
-
1278
- // Decimal digits
1279
- ... ArrayFrom ( { length : 10 } , ( _ , i ) => StringPrototypeCharCodeAt ( '0' ) + i ) ,
1280
-
1281
- 0x2B , // +
1282
- 0x2F , // /
1283
- 0x3D , // =
1273
+ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
1274
+ - 1 , 0 , 0 , - 1 , 0 , 0 , - 1 , - 1 ,
1275
+ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
1276
+ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
1277
+ 0 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
1278
+ - 1 , - 1 , - 1 , 0 , - 1 , - 1 , - 1 , 0 ,
1279
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1280
+ 0 , 0 , - 1 , - 1 , - 1 , 0 , - 1 , - 1 ,
1281
+ - 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1282
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1283
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1284
+ 0 , 0 , 0 , - 1 , - 1 , - 1 , - 1 , - 1 ,
1285
+ - 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1286
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1287
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1288
+ 0 , 0 , 0 , - 1 , - 1 , - 1 , - 1 , - 1 ,
1284
1289
] ;
1285
- const kEqualSignIndex = ArrayPrototypeIndexOf ( kForgivingBase64AllowedChars ,
1286
- 0x3D ) ;
1290
+ /* eslint-enable no-multi-spaces, indent */
1287
1291
1288
1292
function atob ( input ) {
1289
1293
// The implementation here has not been performance optimized in any way and
@@ -1298,16 +1302,17 @@ function atob(input) {
1298
1302
let equalCharCount = 0 ;
1299
1303
1300
1304
for ( let n = 0 ; n < input . length ; n ++ ) {
1301
- const index = ArrayPrototypeIndexOf (
1302
- kForgivingBase64AllowedChars ,
1303
- StringPrototypeCharCodeAt ( input , n ) ) ;
1305
+ const ch = StringPrototypeCharCodeAt ( input , n ) ;
1306
+ const val = kForgivingBase64AllowedChars [ ch & 0x7f ] ;
1304
1307
1305
- if ( index > 4 ) {
1306
- // The first 5 elements of `kForgivingBase64AllowedChars` are
1307
- // ASCII whitespace char codes.
1308
+ if ( ( ch | val ) & ~ 0x7f ) {
1309
+ throw lazyDOMException ( 'Invalid character' , 'InvalidCharacterError' ) ;
1310
+ }
1311
+
1312
+ if ( ch > 0x20 ) {
1308
1313
nonAsciiWhitespaceCharCount ++ ;
1309
1314
1310
- if ( index === kEqualSignIndex ) {
1315
+ if ( ch === 0x3d ) {
1311
1316
equalCharCount ++ ;
1312
1317
} else if ( equalCharCount ) {
1313
1318
// The `=` char is only allowed at the end.
@@ -1318,8 +1323,6 @@ function atob(input) {
1318
1323
// Only one more `=` is permitted after the first equal sign.
1319
1324
throw lazyDOMException ( 'Invalid character' , 'InvalidCharacterError' ) ;
1320
1325
}
1321
- } else if ( index === - 1 ) {
1322
- throw lazyDOMException ( 'Invalid character' , 'InvalidCharacterError' ) ;
1323
1326
}
1324
1327
}
1325
1328
0 commit comments