Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions doc/api/buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,39 @@ appropriate for `Buffer.from()` variants.
[`Buffer.from(string)`][] may also use the internal `Buffer` pool like
[`Buffer.allocUnsafe()`][] does.

### Static method: `Buffer.fromBase64(base64string[, options])`

<!-- YAML
added: REPLACEME
-->

* `base64string` {string} A base64 string to decode.
* `options` {Object}
* `alphabet` {string} One of `'base64'` (default) or `'base64url'`.
* `lastChunkHandling` {string} One of `'loose'` (default), `'strict'`, or `'stop-before-partial'`.
* Returns: {Buffer}

This static method is same as [`Uint8Array.fromBase64()`][], except it
returns `Buffer` rather than `Uint8Array`.

This is not exactly the same as `Buffer.from(base64string, 'base64')`,
and this function will throw `SyntaxError` if input contains non-base64 symbols.

### Static method: `Buffer.fromHex(string)`

<!-- YAML
added: REPLACEME
-->

* `string` {string} A hexadecimal string to decode.
* Returns: {Buffer}

This static method is same as [`Uint8Array.fromHex()`][], except it
returns `Buffer` rather than `Uint8Array`.

This is not exactly the same as `Buffer.from(hexstring, 'hex')`,
and this function will throw `SyntaxError` if input contains non-hex symbols.

### Static method: `Buffer.isBuffer(obj)`

<!-- YAML
Expand Down Expand Up @@ -5540,6 +5573,8 @@ introducing security vulnerabilities into an application.
[`TypedArray.prototype.set()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set
[`TypedArray.prototype.slice()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
[`TypedArray.prototype.subarray()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray
[`Uint8Array.fromBase64()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64
[`Uint8Array.fromHex()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64
[`buf.buffer`]: #bufbuffer
[`buf.compare()`]: #bufcomparetarget-targetstart-targetend-sourcestart-sourceend
[`buf.entries()`]: #bufentries
Expand Down
32 changes: 32 additions & 0 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,38 @@ Buffer.from = function from(value, encodingOrOffset, length) {
);
};

/**
* Same as Uint8Array.fromHex(hexstring), but returns instance of Buffer.
* Not same as Buffer.from(hexstring), as it performs different validations.
* @param {string} str
* @returns {Buffer}
*/
Buffer.fromHex = function fromHex(str) {
// TODO(LiviaMedeiros): replace with primordial once `--js-base-64` is not optional
// eslint-disable-next-line node-core/prefer-primordials
const buf = Uint8Array.fromHex(str);
return fromArrayBuffer(
TypedArrayPrototypeGetBuffer(buf),
TypedArrayPrototypeGetByteOffset(buf),
TypedArrayPrototypeGetByteLength(buf));
};

/**
* Same as Uint8Array.fromBase64(base64string, options), but returns instance of Buffer.
* @param {string} str
* @param {object} [options]
* @returns {Buffer}
*/
Buffer.fromBase64 = function fromBase64(str, options) {
// TODO(LiviaMedeiros): replace with primordial once `--js-base-64` is not optional
// eslint-disable-next-line node-core/prefer-primordials
const buf = Uint8Array.fromBase64(str, options);
return fromArrayBuffer(
TypedArrayPrototypeGetBuffer(buf),
TypedArrayPrototypeGetByteOffset(buf),
TypedArrayPrototypeGetByteLength(buf));
};

/**
* Creates the Buffer as a copy of the underlying ArrayBuffer of the view
* rather than the contents of the view.
Expand Down
34 changes: 34 additions & 0 deletions test/parallel/test-buffer-fromhex-frombase64.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';
require('../common');
const assert = require('assert');
const { Buffer } = require('buffer');

assert.deepStrictEqual(Buffer.fromHex('f00dcafe'), Buffer.from('f00dcafe', 'hex'));
assert.deepStrictEqual(Buffer.fromHex('F00DCAFE'), Buffer.from('f00dcafe', 'hex'));
assert.deepStrictEqual(Buffer.fromHex(''), Buffer.from('', 'hex'));

assert.throws(() => Buffer.fromHex('0x'), { name: 'SyntaxError' });
assert.throws(() => Buffer.fromHex('a'), { name: 'SyntaxError' });
assert.throws(() => Buffer.fromHex(123), { name: 'TypeError' });
assert.throws(() => Buffer.fromHex('abggcd00'), { name: 'SyntaxError' });

assert.deepStrictEqual(Buffer.fromBase64('SGVsbG8='), Buffer.from('SGVsbG8=', 'base64'));
assert.deepStrictEqual(Buffer.fromBase64('SGV sbG8='), Buffer.from('SGVsbG8=', 'base64'));

assert.deepStrictEqual(
Buffer.fromBase64('PGJsZXA-PC9ibGVwPg', { alphabet: 'base64url' }),
Buffer.from('PGJsZXA+PC9ibGVwPg==', 'base64'),
);

assert.deepStrictEqual(Buffer.fromBase64('SGVsbG8=', { lastChunkHandling: 'strict' }), Buffer.from('Hello'));
assert.throws(() => Buffer.fromBase64('SGVsbG8', { lastChunkHandling: 'strict' }), { name: 'SyntaxError' });

assert.deepStrictEqual(
Buffer.fromBase64('SGVsbG8', { lastChunkHandling: 'stop-before-partial' }),
Buffer.from('SGVs', 'base64'),
);

assert.throws(() => Buffer.fromBase64('SGV$sbG8=', {}), { name: 'SyntaxError' });
assert.throws(() => Buffer.fromBase64('S', {}), { name: 'SyntaxError' });
assert.throws(() => Buffer.fromBase64(123), { name: 'TypeError' });
assert.throws(() => Buffer.fromBase64('SGVsbG8=', { alphabet: 'unknown' }), { name: 'TypeError' });
Loading