Skip to content

Commit dc9cd43

Browse files
jasnellruyadorno
authored andcommitted
buffer: implement btoa and atob
Signed-off-by: James M Snell <[email protected]> PR-URL: #37529 Fixes: #3462 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 2e82a97 commit dc9cd43

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

doc/api/buffer.md

+38
Original file line numberDiff line numberDiff line change
@@ -3277,6 +3277,44 @@ While, the `Buffer` object is available as a global, there are additional
32773277
`Buffer`-related APIs that are available only via the `buffer` module
32783278
accessed using `require('buffer')`.
32793279

3280+
### `buffer.atob(data)`
3281+
<!-- YAML
3282+
added: REPLACEME
3283+
-->
3284+
3285+
* `data` {any} The Base64-encoded input string.
3286+
3287+
Decodes a string of Base64-encoded data into bytes, and encodes those bytes
3288+
into a string using Latin-1 (ISO-8859-1).
3289+
3290+
The `data` may be any JavaScript-value that can be coerced into a string.
3291+
3292+
**This function is only provided for compatibility with legacy web platform APIs
3293+
and should never be used in new code, because they use strings to represent
3294+
binary data and predate the introduction of typed arrays in JavaScript.
3295+
For code running using Node.js APIs, converting between base64-encoded strings
3296+
and binary data should be performed using `Buffer.from(str, 'base64')` and
3297+
`buf.toString('base64')`.**
3298+
3299+
### `buffer.btoa(data)`
3300+
<!-- YAML
3301+
added: REPLACEME
3302+
-->
3303+
3304+
* `data` {any} An ASCII (Latin1) string.
3305+
3306+
Decodes a string into bytes using Latin-1 (ISO-8859), and encodes those bytes
3307+
into a string using Base64.
3308+
3309+
The `data` may be any JavaScript-value that can be coerced into a string.
3310+
3311+
**This function is only provided for compatibility with legacy web platform APIs
3312+
and should never be used in new code, because they use strings to represent
3313+
binary data and predate the introduction of typed arrays in JavaScript.
3314+
For code running using Node.js APIs, converting between base64-encoded strings
3315+
and binary data should be performed using `Buffer.from(str, 'base64')` and
3316+
`buf.toString('base64')`.**
3317+
32803318
### `buffer.INSPECT_MAX_BYTES`
32813319
<!-- YAML
32823320
added: v0.5.4

lib/buffer.js

+37-1
Original file line numberDiff line numberDiff line change
@@ -1211,14 +1211,50 @@ if (internalBinding('config').hasIntl) {
12111211
};
12121212
}
12131213

1214+
let DOMException;
1215+
1216+
const lazyInvalidCharError = hideStackFrames((message, name) => {
1217+
if (DOMException === undefined)
1218+
DOMException = internalBinding('messaging').DOMException;
1219+
throw new DOMException('Invalid character', 'InvalidCharacterError');
1220+
});
1221+
1222+
function btoa(input) {
1223+
// TODO(@jasnell): The implementation here has not been performance
1224+
// optimized in any way.
1225+
input = `${input}`;
1226+
for (let n = 0; n < input.length; n++) {
1227+
if (input[n].charCodeAt(0) > 0xff)
1228+
lazyInvalidCharError();
1229+
}
1230+
const buf = Buffer.from(input, 'latin1');
1231+
return buf.toString('base64');
1232+
}
1233+
1234+
const kBase64Digits =
1235+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
1236+
1237+
function atob(input) {
1238+
// TODO(@jasnell): The implementation here has not been performance
1239+
// optimized in any way.
1240+
input = `${input}`;
1241+
for (let n = 0; n < input.length; n++) {
1242+
if (!kBase64Digits.includes(input[n]))
1243+
lazyInvalidCharError();
1244+
}
1245+
return Buffer.from(input, 'base64').toString('latin1');
1246+
}
1247+
12141248
module.exports = {
12151249
Blob,
12161250
Buffer,
12171251
SlowBuffer,
12181252
transcode,
12191253
// Legacy
12201254
kMaxLength,
1221-
kStringMaxLength
1255+
kStringMaxLength,
1256+
btoa,
1257+
atob,
12221258
};
12231259

12241260
ObjectDefineProperties(module.exports, {

0 commit comments

Comments
 (0)