Skip to content

node:http2: populate internal/http2/util for --expose-internals tests [1tpjlb]#29825

Open
robobun wants to merge 4 commits into
mainfrom
farm/4b07618d/internal-http2-util
Open

node:http2: populate internal/http2/util for --expose-internals tests [1tpjlb]#29825
robobun wants to merge 4 commits into
mainfrom
farm/4b07618d/internal-http2-util

Conversation

@robobun

@robobun robobun commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator

What

Populates the Symbol.for("::bunhttp2internals::")].util slot that #31584 added (previously {}) with the helpers Node's --expose-internals tests need from require('internal/http2/util'): assertWithinRange, sessionName, buildNgHeaderString, NghttpError, nghttp2ErrorString, updateOptionsBuffer / optionsBuffer, getAuthority, toHeaderObject, isIllegalConnectionSpecificHeader, isPayloadMeaningless, assertValidPseudoHeader{,Response,Trailer}, assertIsObject, assertIsArray, kSocket, kSensitiveHeaders, kProxySocket, kRequest, kAuthority, kProtocol, MAX_ADDITIONAL_SETTINGS.

Adds a .binding slot alongside it ({ constants, nghttp2ErrorString, optionsBuffer }) and an internal/test/binding entry in the test-common Bun.plugin shim that returns it for internalBinding('http2') and falls through to process.binding(name) otherwise.

While here:

  • ERR_INVALID_ARG_TYPE now matches Node.js when given a single expected type. "Object"/"Function" lowercase to "of type object", and a single CamelCase identifier (Array, RegExp, AbortSignal, Date, …) formats as "an instance of X". Multi-element arrays and pre-formatted strings with spaces/punctuation keep their existing wording so no unrelated callers change. A handful of existing test expectations are updated to the correct Node wording (verified against node -e).
  • Added NGHTTP2_NV_FLAG_NONE / NGHTTP2_NV_FLAG_NO_INDEX to http2.constants (present in Node).
  • Added the ERR_HTTP2_INVALID_CONNECTION_HEADERS code.
  • Guards the ArgList overload of ERR_INVALID_ARG_TYPE against length == 0 (previously underflowed).

Rebase

Rebased onto main after #31584 (node:http2 rewrite) landed. The original approach here created standalone src/js/internal/http2/{util,core}.ts modules wired into HardcodedModule.zig; that's dropped in favour of #31584's Bun.plugin shim in test/js/node/test/common/index.js backed by the Symbol.for("::bunhttp2internals::") export. The helpers now live directly in http2.ts next to the existing ones.

Tests

Moves 10 tests from node-compat group 1tpjlb off the [ FAIL ] list in test/expectations.txt:

test-http2-misc-util
test-http2-server-socket-destroy
test-http2-util-assert-valid-pseudoheader
test-http2-util-asserts
test-http2-util-headers-list
test-http2-util-nghttp2error
test-http2-util-update-options-buffer
test-http2-client-socket-destroy
test-http2-create-client-secure-session
test-http2-server-sessionerror

The remaining 4 (test-http2-client-destroy, test-http2-client-http1-server, test-http2-misbehaving-multiplex, test-http2-server-http1-client) resolve internal/http2/util correctly now but still fail on runtime behaviour (abort-signal listener count, HPE_PAUSED_H2_UPGRADE parser code, reused-stream-id error class) and stay on the expectations list.

@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds three new internal module specifiers for HTTP/2 and test bindings, extracts and centralizes HTTP/2 utilities, adjusts ERR_INVALID_ARG_TYPE formatting to prefer "instance of" for certain types, and introduces many HTTP/2-focused tests plus minor test message updates.

Changes

Cohort / File(s) Summary
Module resolution
src/bun.js/HardcodedModule.zig, src/bun.js/ModuleLoader.zig
Adds enum variants and resolution/aliasing to expose internal:http2/util, internal:http2/core, and internal:test/binding under the expose-internals/debug gate.
HTTP/2 internal utilities
src/js/internal/http2/util.ts
New comprehensive utilities module: header processing, nghttp2 error mapping, optionsBuffer management, validation/assert helpers, constants, and helper APIs exported for internal use.
HTTP/2 core shim
src/js/internal/http2/core.ts
New module exporting HTTP/2 session/stream constructors, server/request/response types, factory helpers, settings helpers, constants and sensitive-headers metadata for internal testing.
Test binding shim
src/js/internal/test/binding.ts
New shim providing internalBinding(name) that returns mapped http2 utilities or falls back to process.binding(name); exported as default.
Node HTTP/2 refactor
src/js/node/http2.ts
Refactors to import shared utilities from internal/http2/util, removes local duplicate implementations, and exposes internal session/stream classes via a $data namespace.
Error formatting and codes
src/bun.js/bindings/ErrorCode.cpp, src/bun.js/bindings/ErrorCode.ts
Changes ERR_INVALID_ARG_TYPE single-type formatting to prefer "instance of" for class-like types and special-cases, and adds ERR_HTTP2_INVALID_CONNECTION_HEADERS to the errors mapping.
HTTP/2 tests (new)
test/js/node/test/parallel/test-http2-*.js, test/js/node/test/parallel/test-http2-util-*.js, test/js/node/test/parallel/test-http2-server-socket-destroy.js
Adds multiple tests covering header building, pseudo-header validation, optionsBuffer updates, nghttp2 error handling, socket destruction behavior, and other HTTP/2 utilities.
Test expectations updated
test/js/node/child_process/..., test/js/node/test/parallel/test-*.js, test/js/web/workers/...
Updates many tests to expect revised TypeError wording using "instance of" instead of "of type" for various argument/type validation messages.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title 'node:http2: populate internal/http2/util for --expose-internals tests [1tpjlb]' clearly and specifically describes the main change: populating the internal/http2/util module for test support.
Description check ✅ Passed The pull request description comprehensively covers both required template sections: a detailed 'What' section explaining the changes and a 'Tests' section verifying the code works, plus additional context about rebase and strategy.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@robobun

robobun commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 8:31 PM PT - Jun 18th, 2026

@robobun, your commit 2161ddc has 5 failures in Build #63432 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 29825

That installs a local version of the PR into your bun-29825 executable, so you can run:

bun-29825 --bun

@robobun

robobun commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator Author

Status

Rebased onto main after #31584 (the node:http2 rewrite) and #31830 (fs). 10/14 tests from node-compat group 1tpjlb now pass.

Test Status
test-http2-util-assert-valid-pseudoheader
test-http2-util-asserts
test-http2-util-headers-list
test-http2-util-nghttp2error
test-http2-util-update-options-buffer
test-http2-misc-util
test-http2-server-socket-destroy
test-http2-client-socket-destroy
test-http2-create-client-secure-session
test-http2-server-sessionerror
test-http2-client-destroy ⏭️ abort-signal listener count + error code differences
test-http2-client-http1-server ⏭️ HPE_INTERNAL vs HPE_PAUSED_H2_UPGRADE
test-http2-misbehaving-multiplex ⏭️ reused-stream error class/code differs from NghttpError
test-http2-server-http1-client ⏭️ bad-magic error class/code differs from NghttpError

All 10 ✅ removed from test/expectations.txt. The helpers live in http2.ts and fill Symbol.for("::bunhttp2internals::")].util / .binding; the test-common Bun.plugin shim gains internal/test/binding. All review threads resolved.


CI (63432, 2161ddc): build finished with all per-context statuses green ({"failures":[], "pending_count":0}). The error annotations are macOS-only flakes pre-existing on main:

  • next-pages/dev-server-ssr-100 + next-build (puppeteer chrome-headless download, also error on 63424/63429)
  • terminal.test.ts subprocess-attach timeout (also error on 63426)
  • grpc-js/test-server SIGTRAP (also error on 63424/63426)
  • fetch-leak.test.ts (also error on 63424/63430)

None touch any file in this PR. claude[bot] review: no issues found, deferring to a maintainer for final sign-off on the cross-cutting ERR_INVALID_ARG_TYPE wording change.

@github-actions

Copy link
Copy Markdown
Contributor

This PR may be a duplicate of:

  1. node: expose internal/* under --expose-internals, implement internal/errors helpers [1v1cy7] #29823 - Both PRs implement --expose-internals infrastructure for internal/* modules, add internal/test/binding, and modify ModuleLoader.zig to gate internal module access

🤖 Generated with Claude Code

@robobun

robobun commented Apr 28, 2026

Copy link
Copy Markdown
Collaborator Author

Re duplicate detection: #29823 (also mine, group 1v1cy7) adds a generic internal/*ResolvedSource.Tag mechanism. This PR adds the http2-specific internal modules on top of the same gate. Whichever lands second gets a straightforward rebase:

The http2 util module, the ERR_INVALID_ARG_TYPE formatter fix, and the 7 node tests are independent of which mechanism lands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/bun.js/bindings/ErrorCode.cpp`:
- Around line 590-600: The code does not guard for expected_types.size() == 0
which causes unsigned underflow when the later code uses length - 1; add an
early check for length == 0 after computing unsigned length and handle it by
calling ERR_INVALID_ARG_TYPE with a safe empty/placeholder expected-type (e.g.,
an empty string or "[]") so no index math or toString() is performed; modify the
branch that currently handles length == 1 / length - 1 to first return when
length == 0 using the same ERR_INVALID_ARG_TYPE path so expected_types and any
subsequent indexing are never accessed when empty.

In `@src/js/internal/http2/util.ts`:
- Around line 559-562: The function assertWithinRange allows NaN because typeof
NaN === "number" and comparisons with NaN are false; update assertWithinRange to
explicitly reject NaN by adding a check (e.g., Number.isNaN(value)) to the
existing conditional so that any NaN value triggers the throw of
$ERR_HTTP2_INVALID_SETTING_VALUE_RangeError with the same message; locate the
function assertWithinRange and augment its if condition to include the NaN test.

In `@src/js/internal/test/binding.ts`:
- Around line 17-20: internalBinding currently returns an empty object when a
binding is missing which masks real missing/native failures; change the fallback
so that when bindings[name] is undefined the function calls and returns
process.binding(name) (preserving the existing behavior of omitting argument
validation), i.e., locate the internalBinding function and replace the final
"return {}" with "return process.binding(name)" so unknown bindings fall through
to Node's native process.binding.

In `@test/js/node/child_process/child_process-node.test.js`:
- Around line 674-678: The test currently asserts the full error.message string
using arg?.toString(), but Node formats the received value with its own
determineSpecificType rendering so the exact text can differ; update the
assertion for fork(...) to instead check error.code === "ERR_INVALID_ARG_TYPE"
and error.name === "TypeError" and assert the message matches a looser pattern
(e.g. use a RegExp like /^The "args" argument must be an instance of Array\.
Received .+/) rather than comparing to arg?.toString() so the test no longer
depends on determineSpecificType formatting.

In `@test/js/node/test/parallel/test-http2-misc-util.js`:
- Around line 19-21: The test's forEach loop is calling sessionName(2) instead
of using the loop variable i, so only the value 2 is actually tested; update the
assertion to call sessionName(i) and keep the rest of the test unchanged (the
loop over [2, '', 'test', {}, [], true] should assert
strictEqual(sessionName(i), '<invalid>') to validate all invalid inputs);
reference: sessionName and the forEach callback variable i in
test-http2-misc-util.js.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6ee828b5-00c6-42d7-bad8-370f930c25ff

📥 Commits

Reviewing files that changed from the base of the PR and between 4d615e8 and cd046c4.

📒 Files selected for processing (25)
  • src/bun.js/HardcodedModule.zig
  • src/bun.js/ModuleLoader.zig
  • src/bun.js/bindings/ErrorCode.cpp
  • src/bun.js/bindings/ErrorCode.ts
  • src/js/internal/http2/core.ts
  • src/js/internal/http2/util.ts
  • src/js/internal/test/binding.ts
  • src/js/node/http2.ts
  • test/js/node/child_process/child_process-node.test.js
  • test/js/node/http2/node-http2.test.js
  • test/js/node/test/parallel/test-assert.js
  • test/js/node/test/parallel/test-buffer-concat.js
  • test/js/node/test/parallel/test-child-process-constructor.js
  • test/js/node/test/parallel/test-dns-setservers-type-check.js
  • test/js/node/test/parallel/test-http2-createserver-options.js
  • test/js/node/test/parallel/test-http2-misc-util.js
  • test/js/node/test/parallel/test-http2-server-socket-destroy.js
  • test/js/node/test/parallel/test-http2-util-assert-valid-pseudoheader.js
  • test/js/node/test/parallel/test-http2-util-asserts.js
  • test/js/node/test/parallel/test-http2-util-headers-list.js
  • test/js/node/test/parallel/test-http2-util-nghttp2error.js
  • test/js/node/test/parallel/test-http2-util-update-options-buffer.js
  • test/js/node/test/parallel/test-process-hrtime.js
  • test/js/node/test/parallel/test-process-setgroups.js
  • test/js/web/workers/message-event.test.ts

Comment thread src/jsc/bindings/ErrorCode.cpp
Comment thread src/js/internal/http2/util.ts Outdated
Comment thread src/js/internal/test/binding.ts Outdated
Comment thread test/js/node/child_process/child_process-node.test.js
Comment thread test/js/node/test/parallel/test-http2-misc-util.js
Comment thread src/js/node/http2.ts Outdated
Comment thread src/js/internal/http2/util.ts Outdated
@Jarred-Sumner Jarred-Sumner force-pushed the farm/4b07618d/internal-http2-util branch from 7e457a8 to 3c643a5 Compare May 4, 2026 10:29
@robobun robobun force-pushed the farm/4b07618d/internal-http2-util branch from 3c643a5 to 1969eee Compare June 18, 2026 02:54
@robobun robobun requested a review from Jarred-Sumner as a code owner June 18, 2026 02:54
@robobun robobun changed the title node:http2: expose internal/http2/util for --expose-internals tests [1tpjlb] node:http2: populate internal/http2/util for --expose-internals tests [1tpjlb] Jun 18, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additional findings (outside current diff — PR may have been updated during review):

  • 🔴 src/jsc/bindings/ErrorCode.ts:102 — Inserting ERR_HTTP2_INVALID_CONNECTION_HEADERS mid-array (alphabetical position) violates the trailing comment in this file — discriminants are index-aligned with the checked-in src/jsc/ErrorCode.rs, which this PR doesn't touch. Every Rust ErrorCode constant ≥86 is now off-by-one against the regenerated C++ errors[] table and ErrorCode::COUNT (324) no longer matches; this is what's failing build-rust on all 8 platforms. Either append the entry after ERR_PROXY_TUNNEL at the end of the array, or regenerate src/jsc/ErrorCode.rs in this PR.

    Extended reasoning...

    What the bug is

    ERR_HTTP2_INVALID_CONNECTION_HEADERS is inserted at line 102 of src/jsc/bindings/ErrorCode.ts, between ERR_HTTP2_INFO_STATUS_NOT_ALLOWED and ERR_HTTP2_INVALID_HEADER_VALUE (the alphabetical position). However, the trailing comment in this same file (lines 334-335) explicitly states:

    // Appended (not alphabetical): discriminants are index-aligned with the checked-in Rust mirror (src/jsc/ErrorCode.rs) — only ever append here.

    The mid-array insertion shifts the index of every subsequent entry by +1, breaking the index alignment with src/jsc/ErrorCode.rs, which is not regenerated in this PR.

    The specific code path that triggers it

    There are two consumers of this array, with different update mechanisms:

    1. C++ side (ErrorCode+List.h / the errors[] table): regenerated at build time from ErrorCode.ts by src/codegen/generate-node-errors.ts. After this PR it will have 325 entries with ERR_HTTP2_INVALID_CONNECTION_HEADERS at index 86 and emit NODE_ERROR_COUNT = 325.
    2. Rust side (src/jsc/ErrorCode.rs): checked-in, not build-generated. Its header (lines 3-8) says "Discriminants MUST stay index-aligned with the C++ errors[] table so Bun__createErrorWithCode picks the correct ctor / name / code triple. Regenerate by re-running the inline extractor against ErrorCode.ts; do not hand-edit individual entries." At HEAD it still has:
      • HTTP2_INFO_STATUS_NOT_ALLOWED = ErrorCode(85) immediately followed by HTTP2_INVALID_HEADER_VALUE = ErrorCode(86) — no entry for the new code
      • pub const COUNT: u16 = 324
      • CODE_STR: [&str; ErrorCode::COUNT as usize] going straight from "ERR_HTTP2_INFO_STATUS_NOT_ALLOWED" to "ERR_HTTP2_INVALID_HEADER_VALUE"

    The PR's changed-files list does not include src/jsc/ErrorCode.rs, and git log -- src/jsc/ErrorCode.rs shows it was last touched before this PR.

    Why existing code doesn't prevent it

    The C++ generator runs every build, so it picks up the new entry automatically. The Rust mirror does not — it must be regenerated manually via the inline extractor mentioned in its header. The only guard is the in-source comment in ErrorCode.ts telling contributors to append, which was overlooked here. The robobun CI comment shows build-rust failing on all 8 platforms (linux x64/aarch64/musl/asan/baseline/android, macOS x64/aarch64) for commit 1969eee, consistent with a count/alignment static assertion firing during the Rust build.

    Step-by-step proof

    1. Before this PR, ErrorCode.ts index 85 = ERR_HTTP2_INFO_STATUS_NOT_ALLOWED, index 86 = ERR_HTTP2_INVALID_HEADER_VALUE. ErrorCode.rs mirrors this: ErrorCode(85) / ErrorCode(86). Both sides have 324 entries.
    2. This PR inserts ["ERR_HTTP2_INVALID_CONNECTION_HEADERS", TypeError] at TS index 86. Now TS index 86 = ERR_HTTP2_INVALID_CONNECTION_HEADERS, index 87 = ERR_HTTP2_INVALID_HEADER_VALUE, …, and the array has 325 entries.
    3. generate-node-errors.ts regenerates the C++ errors[] table to match: C++ index 86 → ERR_HTTP2_INVALID_CONNECTION_HEADERS, NODE_ERROR_COUNT = 325.
    4. ErrorCode.rs is unchanged: Rust still says HTTP2_INVALID_HEADER_VALUE = ErrorCode(86) and COUNT = 324.
    5. Any Rust caller passing ErrorCode::HTTP2_INVALID_HEADER_VALUE (value 86) into Bun__createErrorWithCode would now get an ERR_HTTP2_INVALID_CONNECTION_HEADERS instance — and likewise every one of the ~238 codes from index 86 onward is off by one. The COUNT mismatch (324 vs 325) trips the build-time check, which is why build-rust is red across the board.

    Impact

    The PR cannot build on any platform (all 8 build-rust jobs fail). If the count check were somehow bypassed, every Rust-originated error from index 86 onward would surface with the wrong .code / constructor / name at runtime.

    Fix

    Either of:

    • Append instead of insert: move the new entry to the end of the array, after ["ERR_PROXY_TUNNEL", Error] (in the section already marked "Appended (not alphabetical)"). This requires no Rust change.
    • Regenerate the Rust mirror: re-run the inline extractor against ErrorCode.ts and include the updated src/jsc/ErrorCode.rs (with the new entry at 86, all subsequent discriminants +1, COUNT = 325, and the new CODE_STR row) in this PR.

    The first option is the minimal change and keeps the file's stated invariant.

@robobun

robobun commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator Author

Already fixed in 5353e3e (the review landed against the older diff). ERR_HTTP2_INVALID_CONNECTION_HEADERS is now appended after ERR_PROXY_TUNNEL in ErrorCode.ts, and src/jsc/ErrorCode.rs is updated with the new entry at index 324 and COUNT = 325. Verified locally that the 29 regressed tests (ERR_INVALID_ARG_TYPEERR_INVALID_ADDRESS_FAMILY etc.) pass again.

robobun and others added 3 commits June 19, 2026 02:03
…ls tests

Fills the Symbol.for('::bunhttp2internals::').util slot with the helpers
Node's --expose-internals tests need (assertWithinRange, sessionName,
buildNgHeaderString, NghttpError, nghttp2ErrorString, updateOptionsBuffer,
optionsBuffer, getAuthority, toHeaderObject, isIllegalConnectionSpecificHeader,
isPayloadMeaningless, kSocket, kSensitiveHeaders, ...) and adds a
.binding slot surfaced as internalBinding('http2') via the test-common
Bun.plugin shim.

ERR_INVALID_ARG_TYPE now matches Node.js when given a single expected
type: 'Object'/'Function' lowercase to 'of type object', and a single
CamelCase identifier (Array, RegExp, AbortSignal, ...) formats as
'an instance of X'. Multi-element arrays and pre-formatted strings keep
their existing wording. Updated the handful of test expectations that
were checking Bun's old (incorrect) wording.

Adds NGHTTP2_NV_FLAG_NONE / NGHTTP2_NV_FLAG_NO_INDEX to http2.constants
and the ERR_HTTP2_INVALID_CONNECTION_HEADERS code.

Moves 10 tests from group 1tpjlb off the [ FAIL ] expectations list:
  test-http2-misc-util
  test-http2-server-socket-destroy
  test-http2-util-assert-valid-pseudoheader
  test-http2-util-asserts
  test-http2-util-headers-list
  test-http2-util-nghttp2error
  test-http2-util-update-options-buffer
  test-http2-client-socket-destroy
  test-http2-create-client-secure-session
  test-http2-server-sessionerror
…erting

Inserting in the alphabetical section of ErrorCode.ts shifted every
subsequent discriminant by one, but src/jsc/ErrorCode.rs (checked-in,
not regenerated) still held the old indices. Rust callers ended up
creating the wrong error class/code for everything after the insertion
point (ERR_INVALID_ARG_TYPE reported as ERR_INVALID_ADDRESS_FAMILY,
ERR_IPC_CHANNEL_CLOSED as ERR_IP_BLOCKED, etc.).

Moved the new entry to the append-only tail and mirrored it in
ErrorCode.rs so the discriminants stay aligned.
@robobun robobun force-pushed the farm/4b07618d/internal-http2-util branch from 5353e3e to a4d4ba5 Compare June 19, 2026 02:08
Comment thread src/js/node/http2.ts Outdated
The table was keyed incorrectly: NGHTTP2_ERR_FATAL=-900 is just a
threshold marker, so -901..-904 were all shifted by one (e.g. -903
BAD_CLIENT_MAGIC reported 'SETTINGS frame cannot be flooded'). The
-504..-521 range also had messages assigned to the wrong codes.
Re-transcribed directly from nghttp2_helper.c / nghttp2.h.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found and CI is green; deferring to a human since the ERR_INVALID_ARG_TYPE wording change in ErrorCode.cpp is a cross-cutting behaviour change worth a second pair of eyes.

Extended reasoning...

Overview

This PR populates the internal/http2/util and internal/test/binding shims that Node's --expose-internals tests need, moving 10 http2 tests off the expectations FAIL list. It touches: src/js/node/http2.ts (~290 added lines of test-only helpers — buildNgHeaderString, NghttpError, nghttp2ErrorString, updateOptionsBuffer/optionsBuffer, etc., exposed via the Symbol.for('::bunhttp2internals::') slot); src/jsc/bindings/ErrorCode.cpp (reworks single-type ERR_INVALID_ARG_TYPE formatting to emit "an instance of X" for CamelCase class names and lowercased "of type object/function" for Object/Function, plus a length==0 underflow guard); ErrorCode.ts/ErrorCode.rs (append ERR_HTTP2_INVALID_CONNECTION_HEADERS and bump COUNT); the test-common Bun.plugin shim; and ~8 test files updating expected error wording.

Security risks

None identified. The new helpers are only reachable via the --expose-internals test shim (a Bun.plugin in test/js/node/test/common/index.js), not via the public node:http2 surface. The C++ change is purely error-message formatting; the new length==0 guard removes a latent unsigned-underflow OOB read in the ArgList overload.

Level of scrutiny

Moderate. The http2 additions are low-risk test infrastructure, but the ErrorCode.cpp change is a cross-cutting behaviour change to a globally-used error formatter — every caller that passes a single CamelCase identifier ("Array", "RegExp", "MessagePort", "Date", …) now produces different message text. The isSingleClassName heuristic looks correct and matches Node's /^(?:[A-Z][a-z0-9]*)+$/ classifier, and CI (build 63274) is fully green with the updated test expectations, but the blast radius is wide enough that a maintainer should sign off on the wording policy. The index-aligned ErrorCode.ts/ErrorCode.rs append also deserves a quick eyeball since misalignment there silently shifts every subsequent error code.

Other factors

All prior review threads (CodeRabbit's underflow guard, process.binding fallthrough, my dead-binding nits, and the nghttp2_strerror table mismatch) are resolved. The most recent commit (2161ddc) re-transcribed the nghttp2 error table directly from nghttp2_helper.c per my last comment. The bug-hunting system found nothing on this revision. The PR description is thorough and the remaining 4 still-failing tests are clearly scoped out as runtime-behaviour follow-ups.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant