buffer: fix atob input validation

This commit fixes a few inconsistencies between Node.js `atob`
implementation and the WHATWG spec.

Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode
Fixes: https://github.com/nodejs/node/issues/42646
PR-URL: https://github.com/nodejs/node/pull/42662
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Akhil Marsonya <akhil.marsonya27@gmail.com>
This commit is contained in:
Austin Kelleher 2022-04-12 10:34:59 -04:00 committed by GitHub
parent aa52873887
commit 7533d08b94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 4 deletions

View file

@ -26,7 +26,7 @@ const {
ArrayFrom,
ArrayIsArray,
ArrayPrototypeForEach,
ArrayPrototypeIncludes,
ArrayPrototypeIndexOf,
MathFloor,
MathMin,
MathTrunc,
@ -1259,12 +1259,31 @@ function atob(input) {
if (arguments.length === 0) {
throw new ERR_MISSING_ARGS('input');
}
input = `${input}`;
let nonAsciiWhitespaceCharCount = 0;
for (let n = 0; n < input.length; n++) {
if (!ArrayPrototypeIncludes(kForgivingBase64AllowedChars,
StringPrototypeCharCodeAt(input, n)))
const index = ArrayPrototypeIndexOf(
kForgivingBase64AllowedChars,
StringPrototypeCharCodeAt(input, n));
if (index > 4) {
// The first 5 elements of `kForgivingBase64AllowedChars` are
// ASCII whitespace char codes.
nonAsciiWhitespaceCharCount++;
} else if (index === -1) {
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
}
}
// See #3 - https://infra.spec.whatwg.org/#forgiving-base64
if (nonAsciiWhitespaceCharCount % 4 === 1) {
throw lazyDOMException(
'The string to be decoded is not correctly encoded.',
'InvalidCharacterError');
}
return Buffer.from(input, 'base64').toString('latin1');
}