When pipelined requests arrive in one TCP segment, llhttp_execute()
parses them all in a single call. If a synchronous 'close' event
handler invokes freeParser() mid-execution, cleanParser() nulls out
parser state while llhttp_execute() is still on the stack, crashing on
the next callback.
Add an is_being_freed_ flag that freeParser() sets via
parser.markFreed() before cleaning state. Proxy::Raw checks the flag
before every callback and returns HPE_USER to abort execution early if
set.
PR-URL: https://github.com/nodejs/node/pull/62095
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
The `path` property on `ClientRequest` was only validated at
construction time. Add a getter/setter so that the same
`INVALID_PATH_REGEX` check runs whenever `req.path` is reassigned,
preventing invalid characters from reaching `_implicitHeader()`.
PR-URL: https://github.com/nodejs/node/pull/62030
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
Add validateHeaderName/validateHeaderValue checks for non-link
headers and checkInvalidHeaderChar for the Link value in HTTP/1.1
writeEarlyHints, closing a CRLF injection gap where header names
and values were concatenated into the raw response without
validation.
Also tighten linkValueRegExp to reject CR/LF inside the <...>
URL portion of Link header values.
PR-URL: https://github.com/nodejs/node/pull/61897
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
The WHATWG Streams spec requires that pipeTo's chunk handling must
queue a microtask before calling the write algorithm. This ensures
that enqueue() does not synchronously trigger writes.
Previously, PipeToReadableStreamReadRequest[kChunk] would synchronously
call writableStreamDefaultWriterWrite(), which violated the spec and
caused the WPT test "enqueue() must not synchronously call write
algorithm" to fail.
Fix by wrapping the write operation in queueMicrotask(), which defers
it to the next microtask as required by the spec.
Refs: https://github.com/whatwg/streams/issues/1243
PR-URL: https://github.com/nodejs/node/pull/61800
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Mattias Buelens <mattias@buelens.com>
Add internal fast paths to improve webstreams performance without
changing the public API or breaking spec compliance.
1. ReadableStreamDefaultReader.read() fast path:
When data is already buffered in the controller's queue, return
PromiseResolve() directly without creating a DefaultReadRequest
object. This is spec-compliant because read() returns a Promise,
and resolved promises still run callbacks in the microtask queue.
2. pipeTo() batch read fast path:
When data is buffered, batch reads directly from the controller
queue up to highWaterMark without creating
PipeToReadableStreamReadRequest objects per chunk. Respects
backpressure by checking desiredSize after each write.
Benchmark results:
- pipeTo: ~11% faster (***)
- buffered read(): ~17-20% faster (***)
Co-Authored-By: Malte Ubl <malte@vercel.com>
PR-URL: https://github.com/nodejs/node/pull/61807
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Fixes a race condition in worker thread cwd caching where the counter
is incremented before the directory change completes, allowing workers
to cache stale directory values.
In lib/internal/worker.js, the main thread's process.chdir() wrapper
previously incremented the shared counter before calling the actual
chdir(), creating a race window where workers could read the old
directory but cache it with the new counter value. This caused
subsequent cwd() calls to return incorrect paths until the next chdir().
This fix reorders the operations to change the directory first, then
increment the counter, ensuring workers are only notified after the
directory change completes.
Before fix: 54.28% error rate (311/573 races)
After fix: 0% error rate (0/832 races)
Refs: https://hackerone.com/reports/3407207
Co-authored-by: Giulio Comi
Co-authored-by: Caleb Everett
Co-authored-by: Utku Yildirim
PR-URL: https://github.com/nodejs/node/pull/61664
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Defer socket.destroy() calls in internalConnect and
internalConnectMultiple to the next tick. This ensures that error
handlers have a chance to be set up before errors are emitted,
particularly important when using http.request with a custom
lookup function that returns synchronously.
Previously, if a synchronous lookup function returned an IP that
triggered an immediate error (e.g., via blockList), the error would
be emitted before the HTTP client had set up its error handler
(which happens via process.nextTick in onSocket). This caused
unhandled 'error' events.
Fixes: https://github.com/nodejs/node/issues/48771
PR-URL: https://github.com/nodejs/node/pull/61658
Refs: https://github.com/nodejs/node/pull/51038
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: Jason Zhang <xzha4350@gmail.com>
- Close readline interface after child process exits
Prevents accumulation of event listeners on stderr stream
- Extract watch mode event handler to named function
Allows proper cleanup when watch mode is aborted
These changes prevent unbounded memory growth in long-running
test suites and watch mode sessions.
PR-URL: https://github.com/nodejs/node/pull/60860
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
reporter/utils.js formatTestReport:
1. hasChildren and showErrorDetails are never both true in
existing calls.
2. Thus if hasChildren is true, showErrorDetails is false.
3. So `|| data.details?.error?.failureType === 'subtestsFailed'`
is irrelevant.
4. And `\n${error}` never occurs.
Even though all tests pass after this commit, what if future reporter
code might make calls where both hasChildren and showErrorDetails
are true? I will address this in the last commit of this PR.
Trust me for now.
PR-URL: https://github.com/nodejs/node/pull/59700
Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
The regex constructed by server.addContext() lacked the case-insensitive
flag, causing uppercase or mixed-case SNI hostnames from ClientHello to
miss their intended context and fall back to the default context. This
violates RFC 6066 Section 3, which states that DNS hostnames are
case-insensitive. In mTLS configurations with per-tenant contexts, this
allowed bypassing client certificate authorization by simply
uppercasing the SNI hostname.
Add the 'i' flag to the RegExp in addContext() so that SNI matching
is case-insensitive.
PR-URL: https://github.com/nodejs-private/node-private/pull/857
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
CVE-ID: CVE-2026-48928
Refs: https://hackerone.com/reports/3656869
When the HTTP response ends before the request's 'finish' event fires,
responseOnEnd() and requestOnFinish() can both call responseKeepAlive(),
corrupting the socket that the agent may have already handed to another
request.
This commit adds a !req.destroyed guard to requestOnFinish() so the
second call is skipped when the socket has already been released.
Fixes: https://github.com/nodejs/node/issues/60001
PR-URL: https://github.com/nodejs/node/pull/61710
Reviewed-By: Tim Perry <pimterry@gmail.com>
Ensure that the file handle is closed if header validation fails in
respondWithFile. This prevents ERR_INVALID_STATE errors where a
FileHandle object is closed during garbage collection.
PR-URL: https://github.com/nodejs/node/pull/61707
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>