Skip to content

Commit 7b77944

Browse files
aduh95juanarbol
authored andcommitted
buffer: fix atob input validation
Fixes: #42530 PR-URL: #42539 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mestery <mestery@protonmail.com> Reviewed-By: Akhil Marsonya <akhil.marsonya27@gmail.com>
1 parent 61ea408 commit 7b77944

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

lib/buffer.js

+23-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323

2424
const {
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

12371256
function 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');

test/parallel/test-btoa-atob.js

+3
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ strictEqual(globalThis.btoa, buffer.btoa);
1212
// Throws type error on no argument passed
1313
throws(() => buffer.atob(), /TypeError/);
1414
throws(() => buffer.btoa(), /TypeError/);
15+
16+
strictEqual(atob(' '), '');
17+
strictEqual(atob(' YW\tJ\njZA=\r= '), 'abcd');

0 commit comments

Comments
 (0)