Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: deprecate buffer.slice #41596

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions benchmark/buffers/buffer-slice.js
Expand Up @@ -3,18 +3,22 @@ const common = require('../common.js');
const SlowBuffer = require('buffer').SlowBuffer;

const bench = common.createBenchmark(main, {
type: ['fast', 'slow'],
type: ['fast', 'slow', 'subarray'],
n: [1e6]
});

const buf = Buffer.allocUnsafe(1024);
const slowBuf = new SlowBuffer(1024);

function main({ n, type }) {
const b = type === 'fast' ? buf : slowBuf;
const b = type === 'slow' ? slowBuf : buf;
const fn = type === 'subarray' ?
() => b.subarray(10, 256) :
() => b.slice(10, 256);

bench.start();
for (let i = 0; i < n; i++) {
b.slice(10, 256);
fn();
}
bench.end(n);
}
12 changes: 8 additions & 4 deletions doc/api/buffer.md
Expand Up @@ -254,7 +254,7 @@ In particular:
without copying. This behavior can be surprising, and only exists for legacy
compatibility. [`TypedArray.prototype.subarray()`][] can be used to achieve
the behavior of [`Buffer.prototype.slice()`][`buf.slice()`] on both `Buffer`s
and other `TypedArray`s.
and other `TypedArray`s and should be preferred.
* [`buf.toString()`][] is incompatible with its `TypedArray` equivalent.
* A number of methods, e.g. [`buf.indexOf()`][], support additional arguments.

Expand Down Expand Up @@ -2056,7 +2056,7 @@ If `value` is:
* a string, `value` is interpreted according to the character encoding in
`encoding`.
* a `Buffer` or [`Uint8Array`][], `value` will be used in its entirety.
To compare a partial `Buffer`, use [`buf.slice()`][].
To compare a partial `Buffer`, use [`buf.subarray`][].
* a number, `value` will be interpreted as an unsigned 8-bit integer
value between `0` and `255`.

Expand Down Expand Up @@ -3389,6 +3389,9 @@ console.log(buf.subarray(-5, -2).toString());
<!-- YAML
added: v0.3.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/41596
description: The buf.slice() method has been deprecated.
- version:
- v7.1.0
- v6.9.2
Expand All @@ -3406,11 +3409,11 @@ changes:
**Default:** [`buf.length`][].
* Returns: {Buffer}

> Stability: 0 - Deprecated: Use [`buf.subarray`][] instead.
Returns a new `Buffer` that references the same memory as the original, but
offset and cropped by the `start` and `end` indices.

This is the same behavior as `buf.subarray()`.

This method is not compatible with the `Uint8Array.prototype.slice()`,
which is a superclass of `Buffer`. To copy the slice, use
`Uint8Array.prototype.slice()`.
Expand Down Expand Up @@ -5355,6 +5358,7 @@ introducing security vulnerabilities into an application.
[`buf.keys()`]: #bufkeys
[`buf.length`]: #buflength
[`buf.slice()`]: #bufslicestart-end
[`buf.subarray`]: #bufsubarraystart-end
[`buf.toString()`]: #buftostringencoding-start-end
[`buf.values()`]: #bufvalues
[`buffer.constants.MAX_LENGTH`]: #bufferconstantsmax_length
Expand Down
17 changes: 17 additions & 0 deletions doc/api/deprecations.md
Expand Up @@ -3040,6 +3040,22 @@ const w = new Writable({
});
```

### DEP0158: `buffer.slice(start, end)`

<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/41596
description: Documentation-only deprecation.
-->

Type: Documentation-only

This method was deprecated because it is not compatible with
`Uint8Array.prototype.slice()`, which is a superclass of `Buffer`.

Use [`buffer.subarray`][] which does the same thing instead.

[Legacy URL API]: url.md#legacy-url-api
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
[RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3
Expand All @@ -3062,6 +3078,7 @@ const w = new Writable({
[`WriteStream.open()`]: fs.md#class-fswritestream
[`assert`]: assert.md
[`asyncResource.runInAsyncScope()`]: async_context.md#asyncresourceruninasyncscopefn-thisarg-args
[`buffer.subarray`]: buffer.md#bufsubarraystart-end
[`child_process`]: child_process.md
[`clearInterval()`]: timers.md#clearintervaltimeout
[`clearTimeout()`]: timers.md#cleartimeouttimeout
Expand Down
6 changes: 5 additions & 1 deletion lib/buffer.js
Expand Up @@ -1112,14 +1112,18 @@ function adjustOffset(offset, length) {
return NumberIsNaN(offset) ? 0 : length;
}

Buffer.prototype.slice = function slice(start, end) {
Buffer.prototype.subarray = function subarray(start, end) {
const srcLength = this.length;
start = adjustOffset(start, srcLength);
end = end !== undefined ? adjustOffset(end, srcLength) : srcLength;
const newLength = end > start ? end - start : 0;
return new FastBuffer(this.buffer, this.byteOffset + start, newLength);
};

Buffer.prototype.slice = function slice(start, end) {
return this.subarray(start, end);
};
Comment on lines +1123 to +1125
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we reuse the same method?

Suggested change
Buffer.prototype.slice = function slice(start, end) {
return this.subarray(start, end);
};
Buffer.prototype.slice = Buffer.prototype.subarray;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it this way to preserve the function name (and to a lesser extent for the possibility in the future subarray gets another parameter and to preserve reference inequality). I don't feel strongly about it and we can set it to the same reference directly if people feel that's better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For built-in objects, the ES spec usually reuse the same methods and therefore the name not always match (e.g.: Array.prototype[Symbol.iterator].name === 'values', or Set.prototype.keys.name === 'values'), imo it would make sense to do the same thing here – but I don't feel strongly either way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, actually I see that:

Array.prototype.values === Array.prototype[Symbol.iterator]; // true in v8

And the spec literally says:

The initial value of the @@iterator property is the same function object as the initial value of the Array.prototype.values property.

Neat, I didn't know the spec did that.


function swap(b, n, m) {
const i = b[n];
b[n] = b[m];
Expand Down