Skip to content

Commit

Permalink
buffer: implement btoa and atob
Browse files Browse the repository at this point in the history
Signed-off-by: James M Snell <jasnell@gmail.com>
PR-URL: #37529
Fixes: #3462
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
jasnell authored and targos committed May 1, 2021
1 parent fe0f6a5 commit bf2d9f2
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
38 changes: 38 additions & 0 deletions doc/api/buffer.md
Expand Up @@ -3112,6 +3112,44 @@ While, the `Buffer` object is available as a global, there are additional
`Buffer`-related APIs that are available only via the `buffer` module
accessed using `require('buffer')`.

### `buffer.atob(data)`
<!-- YAML
added: REPLACEME
-->

* `data` {any} The Base64-encoded input string.

Decodes a string of Base64-encoded data into bytes, and encodes those bytes
into a string using Latin-1 (ISO-8859-1).

The `data` may be any JavaScript-value that can be coerced into a string.

**This function is only provided for compatibility with legacy web platform APIs
and should never be used in new code, because they use strings to represent
binary data and predate the introduction of typed arrays in JavaScript.
For code running using Node.js APIs, converting between base64-encoded strings
and binary data should be performed using `Buffer.from(str, 'base64')` and
`buf.toString('base64')`.**

### `buffer.btoa(data)`
<!-- YAML
added: REPLACEME
-->

* `data` {any} An ASCII (Latin1) string.

Decodes a string into bytes using Latin-1 (ISO-8859), and encodes those bytes
into a string using Base64.

The `data` may be any JavaScript-value that can be coerced into a string.

**This function is only provided for compatibility with legacy web platform APIs
and should never be used in new code, because they use strings to represent
binary data and predate the introduction of typed arrays in JavaScript.
For code running using Node.js APIs, converting between base64-encoded strings
and binary data should be performed using `Buffer.from(str, 'base64')` and
`buf.toString('base64')`.**

### `buffer.INSPECT_MAX_BYTES`
<!-- YAML
added: v0.5.4
Expand Down
38 changes: 37 additions & 1 deletion lib/buffer.js
Expand Up @@ -1202,13 +1202,49 @@ if (internalBinding('config').hasIntl) {
};
}

let DOMException;

const lazyInvalidCharError = hideStackFrames((message, name) => {
if (DOMException === undefined)
DOMException = internalBinding('messaging').DOMException;
throw new DOMException('Invalid character', 'InvalidCharacterError');
});

function btoa(input) {
// TODO(@jasnell): The implementation here has not been performance
// optimized in any way.
input = `${input}`;
for (let n = 0; n < input.length; n++) {
if (input[n].charCodeAt(0) > 0xff)
lazyInvalidCharError();
}
const buf = Buffer.from(input, 'latin1');
return buf.toString('base64');
}

const kBase64Digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

function atob(input) {
// TODO(@jasnell): The implementation here has not been performance
// optimized in any way.
input = `${input}`;
for (let n = 0; n < input.length; n++) {
if (!kBase64Digits.includes(input[n]))
lazyInvalidCharError();
}
return Buffer.from(input, 'base64').toString('latin1');
}

module.exports = {
Buffer,
SlowBuffer,
transcode,
// Legacy
kMaxLength,
kStringMaxLength
kStringMaxLength,
btoa,
atob,
};

ObjectDefineProperties(module.exports, {
Expand Down

0 comments on commit bf2d9f2

Please sign in to comment.