2323
2424const {
2525 Array,
26+ ArrayFrom,
2627 ArrayIsArray,
2728 ArrayPrototypeForEach,
29+ ArrayPrototypeIncludes,
2830 MathFloor,
2931 MathMin,
3032 MathTrunc,
@@ -1231,8 +1233,25 @@ function btoa(input) {
12311233 return buf . toString ( 'base64' ) ;
12321234}
12331235
1234- const kBase64Digits =
1235- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' ;
1236+ // Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode
1237+ const kForgivingBase64AllowedChars = [
1238+ // ASCII whitespace
1239+ // Refs: https://infra.spec.whatwg.org/#ascii-whitespace
1240+ 0x09 , 0x0A , 0x0C , 0x0D , 0x20 ,
1241+
1242+ // Uppercase letters
1243+ ...ArrayFrom ( { length : 26 } , ( _ , i ) => StringPrototypeCharCodeAt ( 'A' ) + i ) ,
1244+
1245+ // Lowercase letters
1246+ ...ArrayFrom ( { length : 26 } , ( _ , i ) => StringPrototypeCharCodeAt ( 'a' ) + i ) ,
1247+
1248+ // Decimal digits
1249+ ...ArrayFrom ( { length : 10 } , ( _ , i ) => StringPrototypeCharCodeAt ( '0' ) + i ) ,
1250+
1251+ 0x2B , // +
1252+ 0x2F , // /
1253+ 0x3D , // =
1254+ ] ;
12361255
12371256function atob ( input ) {
12381257 // The implementation here has not been performance optimized in any way and
@@ -1243,7 +1262,8 @@ function atob(input) {
12431262 }
12441263 input = `${ input } ` ;
12451264 for ( let n = 0 ; n < input . length ; n ++ ) {
1246- if ( ! kBase64Digits . includes ( input [ n ] ) )
1265+ if ( ! ArrayPrototypeIncludes ( kForgivingBase64AllowedChars ,
1266+ StringPrototypeCharCodeAt ( input , n ) ) )
12471267 throw lazyDOMException ( 'Invalid character' , 'InvalidCharacterError' ) ;
12481268 }
12491269 return Buffer . from ( input , 'base64' ) . toString ( 'latin1' ) ;
0 commit comments