Skip to content

Commit a924347

Browse files
buffer: atob throw error when the input string is invalid
The specification of `atob` has various different conditions that we need to abide by. The specific changes that were made: * `atob` now immediately throws when `undefined`, `false`, or a `number` is supplied * `atob` now strips ASCII whitespace before attempting to decode * `atob` now validates that the code point's length divided by 4 leaves a remainder that is not 1 See: https://infra.spec.whatwg.org/#forgiving-base64-decode Fixes: #42646
1 parent dfc2dc8 commit a924347

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

lib/buffer.js

+22-1
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,28 @@ function atob(input) {
12591259
if (arguments.length === 0) {
12601260
throw new ERR_MISSING_ARGS('input');
12611261
}
1262-
input = `${input}`;
1262+
1263+
if (input === undefined || input === false || typeof input === 'number') {
1264+
throw lazyDOMException(
1265+
'The string to be decoded is not correctly encoded.',
1266+
'ValidationError');
1267+
}
1268+
1269+
// Remove all ASCII whitespace from data.
1270+
//
1271+
// See #1 - https://infra.spec.whatwg.org/#forgiving-base64
1272+
input = `${input}`.replace(/\s/g, '');
1273+
1274+
// If data's code point length divides by 4 leaving a remainder of 1, then
1275+
// return failure.
1276+
//
1277+
// See #3 - https://infra.spec.whatwg.org/#forgiving-base64
1278+
if (input.length % 4 === 1) {
1279+
throw lazyDOMException(
1280+
'The string to be decoded is not correctly encoded.',
1281+
'ValidationError');
1282+
}
1283+
12631284
for (let n = 0; n < input.length; n++) {
12641285
if (!ArrayPrototypeIncludes(kForgivingBase64AllowedChars,
12651286
StringPrototypeCharCodeAt(input, n)))

test/parallel/test-btoa-atob.js

+9
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,12 @@ throws(() => buffer.btoa(), /TypeError/);
1515

1616
strictEqual(atob(' '), '');
1717
strictEqual(atob(' YW\tJ\njZA=\r= '), 'abcd');
18+
19+
throws(() => buffer.atob(undefined), /ValidationError/);
20+
throws(() => buffer.atob(false), /ValidationError/);
21+
throws(() => buffer.atob(1), /ValidationError/);
22+
throws(() => buffer.atob(0), /ValidationError/);
23+
throws(() => buffer.atob('a'), /ValidationError/);
24+
throws(() => buffer.atob('a '), /ValidationError/);
25+
throws(() => buffer.atob(' a'), /ValidationError/);
26+
throws(() => buffer.atob('aaaaa'), /ValidationError/);

0 commit comments

Comments
 (0)