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

Make Buffer.prototype methods callable with Uint8Array instances #56577

Open
nbbeeken opened this issue Jan 13, 2025 · 0 comments · May be fixed by #56578
Open

Make Buffer.prototype methods callable with Uint8Array instances #56577

nbbeeken opened this issue Jan 13, 2025 · 0 comments · May be fixed by #56578
Labels
feature request Issues that request new features to be added to Node.js.

Comments

@nbbeeken
Copy link
Contributor

What is the problem this feature will solve?

From the docs:

Node.js APIs accept plain Uint8Arrays wherever Buffers are supported as well.

One notable place where plain Uint8Arrays are not always accepted is the methods on the Buffer subclass. Take the method buf.readIntLE(offset, byteLength):

Buffer.prototype.readIntLE.call(Uint8Array.of(1, 0, 0, 0, 0), 0, 3);
// 1

Buffer.prototype.readIntLE.call(Uint8Array.of(1, 0, 0, 0, 0), 0, 4) 
// Uncaught TypeError: this.readInt32LE is not a function
//    at Uint8Array.readIntLE (node:internal/buffer:349:17)

Depending on the byteLength given, the method will respond correctly or throw a TypeError if it happens to be written using a code path that uses an internal method found only on the Buffer prototype.

As a library author, I would also like to easily accept Uint8Arrays wherever Buffers are accepted and not spend time converting the input to a Buffer instance to get useful byte utilities to work on both possible inputs.

What is the feature you are proposing to solve the problem?

I propose to make the few code paths that rely on internal methods invoke those functions in a way that doesn't require them to be defined on the currently bound this value's prototype.

For example:

return this.readInt32LE(offset);

becomes

return FunctionPrototypeCall(readInt32LE, this, offset);

And add coverage for existing and future methods to maintain this contract.

What alternatives have you considered?

A couple but less desirable alternatives:

  • Convert input by invoking Buffer.from(ArrayBuffer, byteOffset, byteLength)
  • Reimplement the methods in library to work with either input
@nbbeeken nbbeeken added the feature request Issues that request new features to be added to Node.js. label Jan 13, 2025
@github-project-automation github-project-automation bot moved this to Awaiting Triage in Node.js feature requests Jan 13, 2025
nbbeeken added a commit to nbbeeken/node that referenced this issue Jan 13, 2025
Removes the reliance on prototype bound methods internally so that Uint8Arrays can be set as the bound `this` value when calling the various Buffer methods. Introduces some additional tamper protection by removing internal reliance on writable properties.

Fixes: nodejs#56577
@nbbeeken nbbeeken linked a pull request Jan 13, 2025 that will close this issue
nbbeeken added a commit to nbbeeken/node that referenced this issue Jan 13, 2025
Removes the reliance on prototype bound methods internally so that Uint8Arrays can be set as the bound `this` value when calling the various Buffer methods. Introduces some additional tamper protection by removing internal reliance on writable properties.

Fixes: nodejs#56577
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js.
Projects
Status: Awaiting Triage
Development

Successfully merging a pull request may close this issue.

1 participant