Commit Graph
6143 Commits
Author SHA1 Message Date
James M Snell 535f934000 stream: fixup writer to terminate on consumer return/throw
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode
PR-URL: https://github.com/nodejs/node/pull/65652
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-09-02 13:14:30 +00:00
James M Snell ae168eac5b stream: ensure iterator cleanup on done, reject, etc
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode
PR-URL: https://github.com/nodejs/node/pull/65652
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-09-02 13:14:29 +00:00
James M Snell 86f9a1b300 stream: fixup cancelation handling in pull()
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode
PR-URL: https://github.com/nodejs/node/pull/65652
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-09-02 13:14:28 +00:00
Tim Perry 09f5aae93b quic: reuse TLS pause machinery to drop event deferral & improve 0RTT
With this change, the TLS pause mechanisms used in node:tls are now made
generic, and used in QUIC to pause the handshake entirely for the
session event, thereby stopping almost all events being emitted
(everything except qlog) so that all the previously existing deferral
machinery is unnecessary.

This is useful immediately to clean up & simplify things, but also
medium term because this makes the 0RTT flow significantly clearer,
which will help with the upcoming dynamic attach for QUIC (which
requires deferring ticket processing & 0RTT delivery until after
user code).

As part of this, this changes the internal flow of how ALPN & SNI are
resolved. Instead of calculating them synchronously within the OpenSSL
callbacks, we precalculate them at the pause, and then the OpenSSL
callbacks just return the precalculated values.

This is intended to only create visible changes to node:quic. Though it
touches node:tls, it preserves all existing behaviour (including
callback order and other details).

Signed-off-by: Tim Perry <pimterry@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65522
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
2026-09-02 10:00:05 +00:00
Filip Skokan 1309975c65 crypto: add strict mode to --force-fips
Allow --force-fips to take an optional provider or strict mode. Keep
provider as the current default and explicit compatibility mode.

In strict mode, return failure from the OpenSSL 3.4+ FIPS indicator
callback when it reports a non-approved operation. Install the callback
for enforcement without implicitly enabling diagnostics;
--enable-fips-indicator-events remains the independent observation
opt-in.

Keep the bare form mapped to provider for compatibility, allowing the
default to change to strict in a future major release. Preserve the mode
when forwarding flags to child test processes, and keep the parser's
internal mode storage out of process.allowedNodeEnvironmentFlags.

Document the callback scope limitations and cover provider
compatibility, validation, synchronous crypto, WebCrypto, Workers, and
opt-in event publication.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65645
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2026-09-02 08:50:36 +00:00
Filip Skokan d5d203a269 crypto: add FIPS indicator diagnostics channel
OpenSSL 3.4 added an indicator callback for operations that its FIPS
provider allows after an approved-mode check has been relaxed.

Publish these indicators on the crypto.fips.indicator diagnostics
channel when Node.js is started with --enable-fips-indicator-events.
Leave the OpenSSL callback unset otherwise so ordinary cryptographic
operations have no indicator callback overhead.

Keep the channel observation-only so enforcement remains the
responsibility of the provider configuration, and independent diagnostic
subscribers can coexist.

Install the native callback during process initialization so it is not
changed while Workers or thread-pool jobs can be using OpenSSL. Preserve
callbacks installed by embedders, and queue bounded, coalesced messages
for asynchronous delivery on the main environment.

Document the channel as best-effort telemetry that cannot identify the
originating call or establish FIPS validation.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65645
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2026-09-02 08:50:34 +00:00
Philipp Dunkel 2247054dda vfs: add ZipProvider
Add a node:vfs provider backed by a node:zlib ZIP archive - a ZipBuffer
held in memory or a ZipFile on disk - that exposes the archive's members
as a virtual filesystem tree. Directories are recognized both explicitly
(a "name/" entry) and implicitly (any entry under "name/"), and a file
opened for writing commits its content as a new archive entry when its
handle is closed. The provider is read-only unless the backing archive
is writable, and offers both asynchronous and synchronous operations.
Available as vfs.ZipProvider.

Signed-off-by: Philipp Dunkel <pip@pipobscure.com>
PR-URL: https://github.com/nodejs/node/pull/64915
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-09-02 07:27:11 +00:00
Daijiro Wachi e06b0f1350 net: recognize bare IPv6 loopback addresses in isLoopback
Signed-off-by: Daijiro Wachi <daijiro.wachi@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/63619
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-09-02 03:55:41 +00:00
Tony Gies 705646f2f7 tls: read the peer certificate chain without consuming it
X509Certificate::GetPeerCert() built the certificate objects by deleting
entries from the stack returned by SSL_get_peer_cert_chain(), which is
owned by the SSL session. The first read emptied it, so any later read
by getPeerCertificate() or getPeerX509Certificate(), on either peer, saw
a truncated chain or nothing. Copy each issuer with X509_dup instead and
leave the session's stack untouched.

onServerSocketSecure() only called getPeerX509Certificate() to check
whether a peer certificate was present, building the whole chain on
every server handshake; that is what first exposed the destructive read.
Use a lightweight hasPeerCertificate() binding for the presence check.

Signed-off-by: Tony Gies <tgies@tgies.net>
PR-URL: https://github.com/nodejs/node/pull/65602
Fixes: https://github.com/nodejs/node/issues/65579
Refs: https://github.com/nodejs/node/pull/64677
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
2026-08-31 18:04:06 +00:00
Seungmin Nam c4336d90c0 permission: support URL and Uint8Array as has()/drop() reference
normalizeReference() adds URL and Uint8Array support to has()/drop();
the existing string/Buffer behavior is unchanged. BufferValue replaces
Utf8Value so a Buffer/TypedArray reference is copied as raw bytes
instead of a lossy UTF-8 conversion.

Signed-off-by: seungmin Nam <nhjbest22@g.skku.edu>
PR-URL: https://github.com/nodejs/node/pull/65492
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-31 14:59:47 +00:00
RafaelGSS 9f1e44cfef fs: do not descend into symlinks for ** unless following symlinks
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs/node/pull/65435
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
2026-08-31 10:19:57 -03:00
Shelley Vohr 2ec0f9ac60 fs: watch directories, not files, in recursive fs.watch fallback
The JavaScript recursive watcher used on platforms without a native one
(notably Linux) armed an fs.watch() handle and a stat() for every file
in the tree, and answered every event by stat()ing and re-reading the
whole directory it happened in. A 13k-entry tree cost 13.5k inotify
watches, ~150 ms and ~50 MB to set up, and appending to one file in a
3900-entry directory cost ~9 ms of CPU per event. A file replaced by
rename() (the usual editor save) also stopped being reported, since its
watch stayed on the old inode.

inotify reports changes to the entries of a watched directory, with
their names, so on Linux watch each directory once (symbolic links keep
their own watcher, as before), keep the set of known paths, and resolve
an event with a single stat() of the named entry: unknown names are
added and reported as 'rename', vanished ones are dropped and reported
as 'rename', file changes are reported as 'change'. kqueue and event
ports only report that a directory changed, so on the other platforms
served by this fallback every file keeps its own watcher and a
directory event rescans that directory, as before. unref() and ref()
now reach the underlying handles.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65486
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
2026-08-31 13:07:39 +00:00
Abhinandan Kumar 8fe4b642ea fs: preserve directory timestamps in cp
This fixes an issue where fs.cp and fs.cpSync (when a filter is
provided) correctly restore mtime and atime on copied files when
preserveTimestamps: true is passed, but skip restoring them for
directories.

The fix applies the existing setDestTimestamps helper to directories,
ensuring it is called after directory creation/copying but before any
modes are restored (since restoring a read-only mode would prevent
timestamp modification).

Note: This fix covers fs.cp() (async, all cases) and fs.cpSync()
when a filter is provided. The native fast path used by cpSync()
without a filter (CpSyncCopyDir in src/node_file.cc) has the
identical gap and is left for a separate follow-up contribution, since
it requires native code changes and a different review path.

Signed-off-by: Abhinandan Kumar <abhi128618@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65540
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
2026-08-31 17:03:33 +08:00
Matteo CollinaandJames M Snell 4d9cb71fa2 vfs: integrate with CJS and ESM module loaders
Co-authored-by: James M Snell <jasnell@gmail.com>
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/63653
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-31 10:31:16 +02:00
Filip Skokan 971cc1c91e fs: fix recursive watch error handling
Recursive watch inverted the throwIfNoEntry check during setup, causing
the default behavior to suppress ENOENT while the opt-out threw it.
Other setup errors were also silently ignored.

Suppress only ENOENT when throwIfNoEntry is false. Propagate all
other setup failures and close watchers created before a partial
failure.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Assisted-by: Codex
PR-URL: https://github.com/nodejs/node/pull/65635
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
2026-08-31 07:05:14 +00:00
Matteo Collina 5947a91327 stream: fix early drain after Utf8Stream reopen
If a 'ready' listener starts a write after reopen(), the reopen path
still emits 'drain' from a nextTick before that write completes, so a
listener reading the file on 'drain' can observe it empty. This is the
race behind the test-fastutf8stream-reopen flake deflaked on the test
side in 2e8a4b1a8c.

Skip the extra emit when a write is in flight: #release() emits the
real 'drain' once the write completes, so no event is lost.

The regression test defers the reopened file's fs.write by one
setImmediate, deterministically landing the write after the nextTick
on which the premature 'drain' used to fire.

Refs: https://github.com/nodejs/node/commit/2e8a4b1a8ce
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/65633
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-31 05:37:01 +00:00
Trivikram Kamat 884f9cd62d zlib: avoid waiting for paused ZIP iterators
Track file-backed contentIterator() reads only while I/O is active.
This lets ZipFile.close() finish when an iterator is paused after
yielding a chunk, while still waiting for reads in flight.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: codex:gpt-5.6-sol
PR-URL: https://github.com/nodejs/node/pull/65278
Fixes: https://github.com/nodejs/node/issues/65277
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-30 12:29:59 +00:00
trivenay f63bffdde0 quic: remove unused fin flag from blob reader wakeup
The fin argument threaded from Blob::Reader::NotifyPull to the JS
blob reader iterator was dead: the only consumer, `if (fin) continue;`,
was the last statement in the loop and behaved identically to falling
through. End-of-stream is always discovered by the subsequent pull
returning EOS, never via the wakeup label. Remove the flag from the
JS iterator, NotifyPull's signature/argv, and the EndReadable call
site. The `!fin` coalescing bypass collapses safely because a parked
reader always has pull_pending_ == false, so the first wakeup after
parking always fires.

Refs: https://github.com/nodejs/node/issues/64767
Signed-off-by: Naman Trivedi <trivenay@amazon.com>
PR-URL: https://github.com/nodejs/node/pull/65315
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
2026-08-30 12:01:15 +00:00
한국 e7a63704f7 crypto: fix public PKCS8 export error
exportKeySpki() already rejects exporting a private key as 'spki'
with an InvalidAccessError, per the Web Crypto export key algorithm
steps for each of RSA, EC, CFRG, ML-DSA, and ML-KEM. exportKeyPkcs8()
was missing the symmetric check: exporting a public key as 'pkcs8'
fell through to the generic "Unable to export ... key using pkcs8
format" NotSupportedError instead of the spec-mandated
InvalidAccessError.

Add the same key-type check to exportKeyPkcs8(), mirroring
exportKeySpki(), and drop the now-redundant type guard around its
call site in exportKeySync(). This also fixes wrapKey(), which
delegates to the same export path.

Add test coverage for both subtle.exportKey('pkcs8', publicKey) and
subtle.wrapKey('pkcs8', publicKey, ...).

Signed-off-by: koreahghg <koreahghg@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65609
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-30 05:43:31 +00:00
Aviv Keller d288ad35c0 worker: add ref/unref to web workers
Signed-off-by: avivkeller <me@aviv.sh>
PR-URL: https://github.com/nodejs/node/pull/65507
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
2026-08-29 18:25:16 +00:00
Jungwon Sohn 7b0de5e9e6 module: derive builtinModules from enabled builtin set
Signed-off-by: sjungwon03 <sjungwon03@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65418
Refs: https://github.com/nodejs/node/pull/56185
Refs: https://github.com/nodejs/node/pull/56870
Refs: https://github.com/nodejs/node/pull/63158
Reviewed-By: Jordan Harband <ljharb@gmail.com>
2026-08-29 01:06:54 +00:00
Filip Skokan 1d8062421e crypto: add a generic MAC API
Add getMacs() and createMac() to node:crypto as a layer on top of
OpenSSL EVP_MAC. Support incremental and streaming operations with
provider parameter validation and configurable output sizes.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65553
Refs: https://github.com/nodejs/node/issues/32433
Refs: https://github.com/nodejs/node/issues/40921
Refs: https://github.com/nodejs/node/issues/48314
Refs: https://github.com/nodejs/node/pull/32448
Refs: https://github.com/nodejs/node/pull/32477
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2026-08-29 00:58:18 +02:00
Aryan 2c07eda791 events: fix weak listener retention overwrite
The weakListeners() retention map in EventTarget stored a single
listener per retainer key. Multiple addEventListener() calls sharing
the same retainer (e.g. two listeners on one target using the same
AbortSignal) silently evicted each other's strong reference, allowing
the evicted listener to be garbage collected before its signal
aborted, so only the most recently registered listener was ever
actually removed on abort.

Changed the retention map to store a Set of listeners per retainer
key instead of a single listener, and added matching cleanup in
remove() so entries are released once their retainer's set is empty.

This also fixes the same class of bug in events.aborted() and the
streams kWeakHandler usage, since both go through the same
EventTarget.prototype.addEventListener() code path.

Fixes: https://github.com/nodejs/node/issues/63954
Signed-off-by: aryan7905 <aryansrivastava354@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/64024
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
2026-08-28 17:42:10 +00:00
René 1c8799df7e util: canonicalize namespaced tags in inspect()
Signed-off-by: Renegade334 <contact.9a5d6388@renegade334.me.uk>
PR-URL: https://github.com/nodejs/node/pull/63257
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2026-08-27 21:15:40 +00:00
Filip Skokan 4788fb7ab8 crypto: validate JWK usages before key_ops
Check requested usages against the JWK public or private key type
before validating key_ops. This preserves the SyntaxError precedence
specified for RSA, EC, CFRG, ML-DSA, and ML-KEM imports.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65550
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-27 21:15:16 +00:00
Filip Skokan 3615979a06 crypto: fix private SPKI export error
Reject SPKI export of a private asymmetric key with InvalidAccessError
as required by the algorithm export steps. Let wrapKey propagate the
same export failure.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65550
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-27 21:15:15 +00:00
Filip Skokan 1a6ab3cc8b crypto: fix RSA-PSS oversized salt handling
Let OpenSSL handle representable salt lengths so verification of an
impossible length resolves false. Guard values outside the native int32
parameter range to prevent SignJob from silently ignoring them.

Move the digest-size helper next to HKDF, its remaining consumer.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65550
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-27 21:15:13 +00:00
James M Snell 05a8e91b5e quic: apply multiple fixes to flow control signaling
Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode/Opus
PR-URL: https://github.com/nodejs/node/pull/65309
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
2026-08-27 18:30:25 +00:00
Rafael Gonzaga d6e67a5e30 permission: block FileHandle fsync and fdatasync
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs/node/pull/65431
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-27 14:10:47 +00:00
Filip Skokan fe6a4cd9c5 crypto: harden X509Certificate state
Construct X509Certificate instances directly on the existing native
X.509 wrapper and keep lazy cached values in private state. Use a
non-throwing native brand check while preserving the existing
structured-clone behavior.

Preserve derived-constructor prototype semantics without rereading
new.target.prototype.

Add coverage for receiver validation, hidden state, prototype edge
cases, subclassing, and structured cloning through workers and message
ports.

Replace the key-only instanceof lint rule with a module-aware crypto
class guard and extend it to X509Certificate. Resolve references by
lexical binding so shadowed constructor names remain valid.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65518
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-08-26 21:36:07 +00:00
Filip Skokan 3541d5d00d crypto: optimize key slot caching
Cache constructor-known KeyObject types in the existing private slot
until a native handle is needed. Prime normal CryptoKey slot arrays
from constructor arguments while retaining the native fallback for
transferred keys.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65518
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-08-26 21:36:05 +00:00
Orgad Shaneh 13220e2a32 http2: fix async context loss when trailers carry END_STREAM
The previous fix (f67e45e070) wrapped header/response event dispatch in
reqAsync.runInAsyncScope(), but missed the stream.push(null) call that
triggers the 'end' event. When END_STREAM arrives on a trailing HEADERS
frame (as gRPC does), the 'end' event fires in the session's async
context instead of the request's context.

Wrap stream.push(null) at end-of-stream in reqAsync.runInAsyncScope()
so that the 'end' event preserves the correct AsyncLocalStorage context.

Refs: https://github.com/nodejs/node/pull/55460
Signed-off-by: Orgad Shaneh <orgad.shaneh@audiocodes.com>
PR-URL: https://github.com/nodejs/node/pull/63814
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-08-26 18:02:50 +00:00
Matteo Collina 6737aa35b8 crypto: prevent Hmac.digest() from returning uninitialized memory
Hmac.prototype._flush was aliased to Hash.prototype._flush, which
finalizes the native HMAC context but never sets the JavaScript-side
kFinalized flag. After an Hmac has been used as a stream, a subsequent
Hmac.prototype.digest() call therefore still believes the object has not
been finalized and calls into C++ a second time. On that second call the
native context has already been reset, so the digest buffer is never
written and Digest::MAX_SIZE bytes of uninitialized stack memory are
returned to JavaScript.

Hash is not affected because Hash::HashDigest caches its digest
(refs #28245); Hmac never received the equivalent protection.

Give Hmac its own _flush that sets kFinalized so repeat digest() calls
after stream use are handled by the existing DEP0206 guard. As defense
in depth, also set buf.len = 0 on the native side when the context has
already been reset so unwritten bytes can never be emitted.

Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/65112
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
2026-08-26 18:02:24 +00:00
Tim Perry 6fa4968eec lib: optimize async context frame activation
Signed-off-by: Tim Perry <pimterry@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65519
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2026-08-26 18:02:03 +00:00
Alexander Lichter a00cf06a0e fs: add maxDepth option to glob
Signed-off-by: Alexander Lichter <github@lichter.io>
PR-URL: https://github.com/nodejs/node/pull/64003
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
2026-08-26 14:07:50 +00:00
James M Snell 4d95cec69b perf_hooks: add CBOR export/import for histogram exchange
Provide a binary export/import mechanism for histograms.

Since there is no standard interchange format for histograms,
using CBOR is meant to make the format as platform/runtime
agnostic as possible while producing a compact/efficient
result. No new dependency is introduced, we just encode
the CBOR directly.

Signed-off-by: James M Snell <jasnell@gmail.com>
Assisted-by: Opencode/Opus
PR-URL: https://github.com/nodejs/node/pull/65434
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2026-08-26 02:28:31 +00:00
JunHwan Choi 96b12934a2 lib: use validateArray for array arguments
Three call sites still duplicated the ArrayIsArray check that
validateArray already performs. Both files were already importing other
validators next to these checks. The error code, argument name and
expected type are unchanged, so the thrown error stays identical.

The ArrayIsArray primordial is no longer used in histogram.js and is
dropped from its destructuring; blocklist.js still uses it elsewhere.

The existing tests only asserted the error code, so assertions covering
the full error message are added for all three call sites. They pass
both before and after this change.

Refs: https://github.com/nodejs/node/pull/64959
Assisted-by: claude:fable-5
Signed-off-by: JunHwan Choi <devjunsday@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65344
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
2026-08-25 16:57:32 -07:00
Filip Skokan e7a69c4992 crypto: discover ciphers from OpenSSL providers
Enumerate usable ciphers and aliases from activated OpenSSL 3 providers
instead of maintaining lists of provider-only algorithms. Skip numeric
OID aliases and filter NULL, TLS composite, multiblock, and
encrypt-then-MAC implementations that the Cipher APIs cannot use.
Preserve the OpenSSL 1.1.1 and BoringSSL paths.

Expose CBC-CTS, SM4-GCM, SM4-CCM, SM4-XTS, and additional AES key wrap
implementations. Add `ctsMode` (CS1/CS2/CS3) and `xtsStandard`
(GB/IEEE) options for selecting provider CTS and SM4-XTS variants.

Keep ordinary cipher construction on the original binding and legacy
lookup paths.

Lazily cache successful provider fetches per Environment for
string initialization and `getCipherInfo()`.
Index entries by case-insensitive query, canonical, and alias names.
Deduplicate owners by provider and canonical identity. Return borrowed
pointers on warm hits.

Use the shared process-wide FIPS-state generation to invalidate
per-Environment cipher caches and refresh `getCiphers()` snapshots in
the main thread and workers. Existing cipher contexts retain their
implementation and can finish across a transition. Release provider
owners before unloading worker addon DSOs.

Enforce one-shot updates for CBC-CTS, AES key wrap, SIV/GCM-SIV, and
CCM decryption. Reject finalization without required input or CCM tags,
and defer authentication failures to `final()`. Document streaming and
XTS data-unit constraints.

Add known-answer vectors, option validation, provider round trips,
cache, worker, snapshot, FIPS transition, and construction benchmark
coverage.

Fixes: https://github.com/nodejs/node/issues/43040
Fixes: https://github.com/nodejs/node/issues/64866
Refs: https://github.com/nodejs/node/issues/62982
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65484
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-08-25 23:11:06 +00:00
Filip Skokan 025e88f981 crypto: discover hashes from OpenSSL providers
Enumerate usable digests and aliases from activated OpenSSL 3 providers
rather than relying only on the legacy digest registry. Normalize
provider aliases, omit numeric OIDs and NULL, and validate them against
the active default property query. Preserve legacy names and the OpenSSL
1.1.1 and BoringSSL paths.

Expose KECCAK-KMAC-128, KECCAK-256, SHA256-192, and other provider
digests. Add `functionName` and `customization` options for cSHAKE
digests in `createHash()` and `crypto.hash()` with OpenSSL 4.0 or later.

Resolve provider-only digest names across hashing, HMAC, KDF, signing,
verification, and RSA digest options. Keep ordinary hash construction
and one-shot hashing on the original binding arities and direct
initialization paths. Use parameterized setup only when cSHAKE options
are supplied.

Lazily cache successful provider fetches per Environment.
Index entries by case-insensitive query, canonical, and alias names.
Deduplicate owners by provider and canonical identity. Return borrowed
pointers on warm hits.

Introduce a process-wide FIPS-state generation that advances only after
successful, state-changing `setFips()` calls. Use it to invalidate
per-Environment digest caches and refresh `getHashes()` snapshots in the
main thread and workers. Keep cache IDs monotonic across invalidation
because JavaScript Realms can retain them. Existing hash contexts can
finish across a transition.

Release provider owners before unloading worker addon DSOs. Document
provider-dependent availability and operation-specific restrictions.
Add known-answer vectors, option validation, provider resolution,
property-query, FIPS transition, worker, snapshot, and cross-API
coverage.

Refs: https://github.com/nodejs/node/issues/62982
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65484
Fixes: https://github.com/nodejs/node/issues/43040
Fixes: https://github.com/nodejs/node/issues/64866
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-08-25 23:11:05 +00:00
Filip Skokan 7aaf9b44d7 crypto: avoid throwing CryptoKey brand checks
Use the native CryptoKey FunctionTemplate brand check instead of
probing slot access and catching ERR_INVALID_THIS. Keep a private-field
fast path for ordinary same-realm CryptoKeys.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65503
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-08-25 17:19:35 +00:00
Filip Skokan ebd88be3dd crypto: avoid throwing KeyObject brand checks
Use the native KeyObject FunctionTemplate brand check instead of
probing slot access and catching ERR_INVALID_THIS. Keep a private-field
fast path for ordinary same-realm KeyObjects.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65503
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2026-08-25 17:19:34 +00:00
Szymon Łągiewka 984e46f322 events: inline iterationCondition hybrid dispatch closure
While more readable, the removed closure overhead unlocks 10-20% in
eventtarget.js benchmark.

Signed-off-by: Szymon Łągiewka <slagiewka@users.noreply.github.com>
PR-URL: https://github.com/nodejs/node/pull/64473
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
2026-08-25 07:53:50 +00:00
Szymon Łągiewka 59dd75b93b events: inline createEvent hybrid dispatch closure
Originally added in 16b11cd2ad, it first
had three callers. Now there's only one branch requireing it.

Signed-off-by: Szymon Łągiewka <slagiewka@users.noreply.github.com>
PR-URL: https://github.com/nodejs/node/pull/64473
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
2026-08-25 07:53:48 +00:00
Shelley Vohr e618b1b092 fs: stop stat()ing every entry in recursive readdir
readdir({ recursive: true }) asked the binding for names only and then
called internalModuleStat() on every entry to find the directories to
descend into; with withFileTypes it built the Dirents and still stat()ed
every entry that was not already a directory. Both variants also ran
path.join() and path.relative() per entry to build the relative result.

Ask the binding for file types in all cases, descend into directories
directly, and only stat() symbolic links and entries of unknown type
(which is what could point to a directory). The relative name is the
parent's prefix plus the entry name. Results, their order and the
symlink-following behavior are unchanged for fs.readdirSync, fs.readdir
and fs.promises.readdir.

The known_issues test for Buffer paths (#58892) called back without
checking the error; the error now reaches the callback instead of being
thrown from the completion handler, so the test asserts success to keep
expressing the issue.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65487
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
2026-08-25 07:53:37 +00:00
Trivikram Kamat 4b5e86c4e2 stream: normalize fused stateless transform results
Normalize each stateless transform result before passing it to
the next transform in a fused run. This ensures that subsequent
transforms always receive Uint8Array[] batches in both synchronous
and asynchronous pipelines.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: codex:gpt-5.6-sol
PR-URL: https://github.com/nodejs/node/pull/65367
Fixes: https://github.com/nodejs/node/issues/65366
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-25 02:52:18 +00:00
Matteo Collina f2c7f1bcf8 stream: encode whole chunks in TextEncoderStream
The encode-and-enqueue transform walked the chunk code unit by code
unit, materializing a single-character string per index and building
the output with string concatenation. The only state that crosses
chunks is a trailing high (leading) surrogate, and TextEncoder.encode's
USVString conversion already replaces every interior lone surrogate
with U+FFFD, which is exactly what the spec loop produces. Join a
pending high surrogate with the incoming chunk, hold back a new
trailing high surrogate, and encode the rest in a single native call.

The streaming decode path also reuses a single options object instead
of allocating { stream: true } per chunk.

An encoding-streams benchmark is added since the suite had no
TextEncoderStream/TextDecoderStream row. Encoding improves by ~546%
with 1KB string chunks and ~20% with 16-character chunks; decode is
unchanged.

Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/65414
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Mattias Buelens <mattias@buelens.com>
2026-08-24 18:17:10 +00:00
Hamid Reza Ghavami f509cf1d08 util: allow single-line format when break length is infinite
Signed-off-by: Hamid Reza Ghavami <hamidr.ghavami@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/64238
Reviewed-By: Jordan Harband <ljharb@gmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
2026-08-24 14:31:34 +00:00
Dushyant Singh HadaandCursor 5b316e5402 util: fix OSC 8 hyperlink stripping in stripVTControlCharacters
The bundled ansi-regex OSC pattern used a restrictive URI
character class that failed when URIs contained RFC 3986-valid
characters such as parentheses.

Match OSC sequences generically as ESC ] ... ST, aligned with
ansi-regex v6.2.0.

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: dushyant <dushyanthada90@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/64319
Fixes: https://github.com/nodejs/node/issues/64313
Reviewed-By: Aviv Keller <me@aviv.sh>
2026-08-24 03:14:23 +00:00
Trivikram Kamat f96dccc271 stream: prevent share from eagerly draining source
Wait for buffer space after drop-newest discards an upstream result.
This keeps one consumer pull from draining the source or looping
indefinitely while a slower consumer keeps the buffer full.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: codex:gpt-5.6-sol
PR-URL: https://github.com/nodejs/node/pull/65338
Fixes: https://github.com/nodejs/node/issues/65337
Reviewed-By: James M Snell <jasnell@gmail.com>
2026-08-23 21:43:31 +00:00
Antoine du Hamel 057e591f7c lib,src: remove --no-experimental-websocket CLI flag
Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/65284
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
2026-08-23 21:16:19 +00:00