Skip to content

fix(ext/node): make Buffer.prototype methods generic-callable#33466

Merged
bartlomieju merged 3 commits into
denoland:mainfrom
nathanwhitbot:fix/node-compat-iter29
Apr 25, 2026
Merged

fix(ext/node): make Buffer.prototype methods generic-callable#33466
bartlomieju merged 3 commits into
denoland:mainfrom
nathanwhitbot:fix/node-compat-iter29

Conversation

@nathanwhitbot

Copy link
Copy Markdown
Contributor

Match Node's lib/buffer.js so that Buffer.prototype.<method>.call(uint8array, ...) behaves identically to buffer.<method>(...). Without this, calls fall through to Uint8Array.prototype methods (or to undefined slice/write helpers) and produce wrong results.

Changes

  • includes: dispatch through bidirectionalIndexOf instead of this.indexOf, so the call doesn't resolve to Uint8Array.prototype.indexOf.
  • readUIntLE / readUIntBE / readIntLE / readIntBE: dispatch the byteLength = 1/2/4 cases through Buffer.prototype.read{U}Int{8,16,32}{LE,BE}.call(this, offset).
  • toString / write fast paths: route to Buffer.prototype.{base64,utf8}{Slice,Write}.
  • encodingOps (ascii/base64/base64url/hex/latin1/ucs2/utf8/utf16le): route slice/write through Buffer.prototype.<encoding>{Slice,Write}.call so they work when buf is a plain Uint8Array.
  • inspect: use this.constructor.name (default Buffer on failure) and route the hex toString through Buffer.prototype.toString.call so generic calls produce <Uint8Array ...> in the same hex form as <Buffer ...>.

Enables parallel/test-buffer-generic-methods.js in the node_compat suite.

Match Node's lib/buffer.js so that Buffer.prototype.<method>.call(uint8array, ...)
behaves identically to buffer.<method>(...). Without this, calls fall through
to Uint8Array.prototype methods (or to undefined slice/write helpers) and
produce wrong results.

- includes: dispatch through bidirectionalIndexOf instead of this.indexOf, so
  the call doesn't resolve to Uint8Array.prototype.indexOf.
- readUIntLE/BE, readIntLE/BE: dispatch the byteLength=1/2/4 cases through
  Buffer.prototype.read{U}Int{8,16,32}{LE,BE}.call(this, offset).
- toString/write fast paths: route to Buffer.prototype.{base64,utf8}{Slice,Write}.
- encodingOps.{ascii,base64,base64url,hex,latin1,ucs2,utf8,utf16le}: route
  slice/write through Buffer.prototype.<encoding>{Slice,Write}.call so they
  work when buf is a plain Uint8Array.
- inspect: use this.constructor.name (default Buffer on failure) and route
  the hex toString through Buffer.prototype.toString.call so generic calls
  produce <Uint8Array ...> in the same hex form as <Buffer ...>.

Enables parallel/test-buffer-generic-methods.js in the node_compat suite.

@nathanwhitbot nathanwhitbot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Faithful port of Node's lib/buffer.jsBuffer.prototype.<method>.call(this, ...) dispatch through prototype, this.constructor.name with try/catch fallback in inspect, bidirectionalIndexOf directly in includes. Encoding ops mirror Node's standalone-helper shape via .call(buf, ...). The Buffer.prototype.slice keeps this.subarray deliberately so generic Uint8Array this stays a Uint8Array — matches Node L869. ObjectPrototypeHasOwnProperty correctly added to primordials destructure. LGTM.

prefer-primordials lint flags Buffer.prototype.<method>.call(...) as
global intrinsic access. Switch to FunctionPrototypeCall imported from
the primordials object.
ban-unused-ignore lint flagged the deno-lint-ignore prefer-primordials
comment on the this.subarray call — the underlying violation is gone
since the dispatch is on a Uint8Array prototype method, not a global
intrinsic.
@bartlomieju
bartlomieju merged commit b88d732 into denoland:main Apr 25, 2026
112 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants