mirror of
https://github.com/HeyPuter/puter.git
synced 2026-10-19 10:01:59 +00:00
fix(ai): reject non-ASCII base64 that Node decodes by its low byte
Node reads code units above 0xFF by their low byte, so U+012B decodes as '+' and keeps the decoded length the input predicts. Require ASCII (~1-2 ms for 43M chars) before the length check.
This commit is contained in:
1 parent
9d9c0e85fd
commit
e16cfb8302
2 files changed
+4
No files matched your search
@@ -35,6 +35,7 @@ describe('decodeStrictBase64', () => {
|
||||
['the URL-safe alphabet', 'a-b_'],
|
||||
['whitespace', 'YW Jj'],
|
||||
['a character outside the alphabet', 'YW*j'],
|
||||
['a non-ASCII character whose low byte is in the alphabet', 'YWJī'],
|
||||
['padding mid-string', 'YQ==YWJj'],
|
||||
['three pad characters', 'Y==='],
|
||||
])('rejects %s', (_label, value) => {
|
||||
|
||||
@@ -59,6 +59,9 @@ const MP4_BRANDS = new Set([
|
||||
*/
|
||||
export function decodeStrictBase64(value: string): Buffer | null {
|
||||
if (value.length === 0 || value.length % 4 !== 0) return null;
|
||||
// Node decodes a code unit above 0xFF by its low byte (`ī` as `+`), so
|
||||
// only ASCII is decoded.
|
||||
if (Buffer.byteLength(value, 'utf8') !== value.length) return null;
|
||||
// Node also decodes the URL-safe alphabet.
|
||||
if (value.includes('-') || value.includes('_')) return null;
|
||||
const padding = value.endsWith('==') ? 2 : value.endsWith('=') ? 1 : 0;
|
||||
|
||||
Reference in new issue
Block a user