Skip to content

Commit fa9015c

Browse files
committed
perf: trust Uint8Array.fromBase64 to check non-whitespace chars
1 parent d11ab4b commit fa9015c

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,15 @@ const hasBase64Builtin: boolean = /* @__PURE__ */ (() =>
451451
typeof (Uint8Array as any).from([]).toBase64 === 'function' &&
452452
typeof (Uint8Array as any).fromBase64 === 'function')();
453453

454+
// ASCII whitespace is U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE
455+
const ASCII_WHITESPACE = /[\t\n\f\r ]/
456+
454457
const decodeBase64Builtin = (s: string, isUrl: boolean) => {
455458
astr('base64', s);
456-
const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;
457459
const alphabet = isUrl ? 'base64url' : 'base64';
458-
if (s.length > 0 && !re.test(s)) throw new Error('invalid base64');
460+
// Per spec, .fromBase64 already throws on any other non-alphabet symbol except ASCII whitespace
461+
// And checking just for whitspace makes decoding about 3x faster than a full range check
462+
if (s.length > 0 && ASCII_WHITESPACE.test(s)) throw new Error('invalid base64');
459463
return (Uint8Array as any).fromBase64(s, { alphabet, lastChunkHandling: 'strict' });
460464
};
461465

0 commit comments

Comments
 (0)