Skip to content

Commit 56a8269

Browse files
committed
feat: fromBase64 never returns pooled Uint8Arrays
1 parent 6034e9c commit 56a8269

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

base64.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ if (Uint8Array.fromBase64) {
140140
}
141141
} else if (haveNativeBuffer) {
142142
fromBase64impl = (str, isBase64url, padding, format) => {
143-
const arr = Buffer.from(str, 'base64')
143+
const size = Buffer.byteLength(str, 'base64')
144+
const arr = Buffer.allocUnsafeSlow(size) // non-pooled
145+
if (arr.base64Write(str) !== size) throw new SyntaxError(E_PADDING)
144146
// Rechecking by re-encoding is cheaper than regexes on Node.js
145147
const got = isBase64url ? maybeUnpad(str, padding === false) : maybePad(str, padding !== true)
146148
const valid = isBase64url ? arr.base64urlSlice(0, arr.length) : arr.base64Slice(0, arr.length)

tests/base64.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,21 @@ describe('fromBase64', () => {
171171
}
172172
})
173173
})
174+
175+
test('fromBase64 returns non-pooled Uint8Array instances', (t) => {
176+
for (let i = 0; i < 256; i++) {
177+
t.assert.strictEqual(fromBase64('A'.repeat(128 * 4)).buffer.byteLength, 128 * 3)
178+
}
179+
180+
for (let i = 0; i < 256; i++) {
181+
t.assert.strictEqual(fromBase64('A'.repeat(64 * 4)).buffer.byteLength, 64 * 3)
182+
}
183+
184+
for (let i = 0; i < 512; i++) {
185+
t.assert.strictEqual(fromBase64('A'.repeat(32 * 4)).buffer.byteLength, 32 * 3)
186+
}
187+
188+
for (let i = 0; i < 512; i++) {
189+
t.assert.strictEqual(fromBase64('').buffer.byteLength, 0)
190+
}
191+
})

0 commit comments

Comments
 (0)