Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
6fb5bb5
quic: fix broken listEndpoints export, test callbacks & nghttp3 include
pimterry Jun 14, 2026
521e6c1
crypto: fix unhandled error in Hash._transform
haramj Jun 14, 2026
f29949e
src: handle empty MaybeLocal in cjs_lexer::Parse
anonrig Jun 15, 2026
4e8db7f
util: fix -0 formatting when numericSeparator is enabled
watilde Jun 9, 2026
b7b5706
doc: fix typo in cli.md
watilde Jun 15, 2026
a42aa0a
debugger: await initialization after run and restart
trivikr Jun 15, 2026
b8d3f5e
test: update WPT for urlpattern to 23aac92784
nodejs-github-bot Jun 16, 2026
7e85198
util: fix scientific notation formatting
watilde Jun 16, 2026
e55eeaf
stream: fix dropped first chunk in Utf8Stream buffer mode
watilde Jun 16, 2026
6f3e342
test: update WPT for url to d4598eba09
nodejs-github-bot Jun 14, 2026
1bac086
stream: only pass the expected number of parameters to callbacks
aduh95 Jun 16, 2026
622f4e1
crypto: make webcrypto aliasKeyFormat directional
panva Jun 16, 2026
1d62b24
sqlite: do not leave database open after failed open
anonrig Jun 16, 2026
6723b1e
doc: fix incorrect test runner mock examples
emmayusufu Jun 17, 2026
8490456
doc,crypto: mark argon2 and encap/decap as stable
panva Jun 17, 2026
dfefe03
benchmark: add child_process async path baselines
anonrig Jun 17, 2026
cf039e2
tls: route event listener exceptions through error handlers
aduh95 Jun 18, 2026
16c511c
debugger: defer probe pause handling until startup
trivikr Jun 18, 2026
d73c832
doc: clarify callback exceptions
mcollina Jun 18, 2026
b351fa5
child_process: serialize advanced IPC messages natively
anonrig Jun 18, 2026
8e769b1
crypto: use EVP_MAC for HMAC on OpenSSL >=3
panva Jun 19, 2026
02cbcc3
tools: update the llhttp updater script
aduh95 Jun 19, 2026
957f0d1
build: add QUIC CI job for PRs matching QUIC related paths
pimterry Jun 19, 2026
62a822e
crypto,tls: do not ignore BN_get_word error
tniessen Jun 19, 2026
7e4b860
deps: update OpenSSL build config to support compression
pimterry Mar 12, 2026
bd1ea8c
tls: add certificateCompression option
pimterry Mar 11, 2026
03f0b88
inspector: fix inspector.close() documented behavior
legendecas Jun 20, 2026
14d0bb1
src: guard OpenSSL compression header include
panva Jun 20, 2026
fdc56ab
stream: fix Utf8Stream stall after full write of multi-byte data
watilde Jun 17, 2026
bca6ae6
doc: fix typo in util.md
watilde Jun 17, 2026
1a3bbdc
build: suppress compiler warnings for histogram
richardlau Jun 20, 2026
19368cd
doc: add aduh95 to last security release steward
aduh95 Jun 20, 2026
6ef38f3
deps: update acorn to 8.17.0
nodejs-github-bot Jun 20, 2026
69084ad
child_process: pass spawn options to the binding positionally
anonrig Jun 20, 2026
0dc2040
tools: bump js-yaml from 4.1.1 to 4.2.0 in /tools/eslint
dependabot[bot] Jun 20, 2026
2ab22ff
tools: bump js-yaml from 4.1.1 to 4.2.0 in /tools/lint-md
dependabot[bot] Jun 20, 2026
5c5dc77
test: mark test-debugger-run-after-quit-restart as flaky on macOS
mcollina Jun 20, 2026
1d1a925
src: omit unconvertible names in cjs_lexer::Parse
anonrig Jun 20, 2026
c40638b
tools: update sccache to v0.16.0
targos Jun 20, 2026
57d0b79
fs: do not treat EPERM as ENOTEMPTY on Windows
PickBas Jun 21, 2026
f67b431
test: tolerate duplicate watch change events
trivikr Jun 21, 2026
8276033
stream: fix Writable.toWeb() desiredSize for non-object-mode
mcollina Jun 21, 2026
2c08dd7
watch: print name of changed file that triggers restart
marcopiraccini Jun 22, 2026
0855d45
debugger: lazily wait for initial break output
trivikr Jun 22, 2026
d03a6b2
doc: add sxa GPG key (ed25519)
sxa Jun 29, 2026
5c2cf58
deps: V8: backport bef0d9c1bc90
joyeecheung Mar 5, 2026
0eeb4f5
src: do not enable wasm trap handler if there's not enough vmem
joyeecheung Feb 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/build-tarball.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
with:
version: v0.12.0
version: v0.16.0
- name: Environment Information
run: npx envinfo
- name: Download tarball
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage-linux-without-intl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
with:
version: v0.12.0
version: v0.16.0
- name: Environment Information
run: npx envinfo
- name: Install gcovr
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
with:
version: v0.12.0
version: v0.16.0
- name: Environment Information
run: npx envinfo
- name: Install gcovr
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-internet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
with:
version: v0.12.0
version: v0.16.0
- name: Environment Information
run: npx envinfo
- name: Build
Expand Down
82 changes: 82 additions & 0 deletions .github/workflows/test-linux-quic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Test Linux (with QUIC)

on:
workflow_dispatch:
pull_request:
paths:
- .github/workflows/test-linux-quic.yml
- configure.py
- node.gyp
- node.gypi
- deps/ngtcp2/**
- deps/nghttp3/**
- deps/openssl/**
- src/quic/**
- src/node_bob*
- lib/quic.js
- lib/http3.js
- lib/internal/quic/**
- lib/stream/iter.js
- lib/internal/streams/iter/**
- test/cctest/test_quic_*
- test/common/quic*
- test/common/quic/**
- test/parallel/*quic*
- test/parallel/test-stream-iter-*
types: [opened, synchronize, reopened, ready_for_review]

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

env:
PYTHON_VERSION: '3.14'
FLAKY_TESTS: keep_retrying
CLANG_VERSION: '19'
CC: ${{ (github.base_ref == 'main' || github.ref_name == 'main') && 'sccache' || '' }} clang-19
CXX: ${{ (github.base_ref == 'main' || github.ref_name == 'main') && 'sccache' || '' }} clang++-19
SCCACHE_GHA_ENABLED: ${{ github.base_ref == 'main' || github.ref_name == 'main' }}
SCCACHE_IDLE_TIMEOUT: '0'
RUSTC_VERSION: '1.82'

permissions:
contents: read

jobs:
test-quic:
if: github.event.pull_request.draft == false
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
path: node
- name: Install Clang ${{ env.CLANG_VERSION }}
uses: ./node/.github/actions/install-clang
with:
clang-version: ${{ env.CLANG_VERSION }}
- name: Install Rust ${{ env.RUSTC_VERSION }}
run: |
rustup override set "$RUSTC_VERSION"
rustup --version
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ env.PYTHON_VERSION }}
allow-prereleases: true
- name: Set up sccache
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
with:
version: v0.12.0
- name: Environment Information
run: npx envinfo
- name: Build
working-directory: node
run: make build-ci -j4 V=1 CONFIG_FLAGS="--error-on-warn --v8-enable-temporal-support --experimental-quic"
- name: Test
working-directory: node
run: make test-ci -j1 V=1 TEST_CI_ARGS="-p actions --measure-flakiness 9"
- name: Ensure running tests did not cause any change in the tree
working-directory: node
run: git add -A && git diff --name-only --exit-code --staged
2 changes: 1 addition & 1 deletion .github/workflows/test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
with:
version: v0.12.0
version: v0.16.0
- name: Environment Information
run: npx envinfo
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
if: github.base_ref == 'main' || github.ref_name == 'main'
uses: Mozilla-Actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
with:
version: v0.12.0
version: v0.16.0
- name: Environment Information
run: npx envinfo
# The `npm ci` for this step fails a lot as part of the Test step. Run it
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,8 @@ Primary GPG keys for Node.js Releasers (some Releasers sign with subkeys):
`C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C`
* **Ruy Adorno** <<[email protected]>>
`108F52B48DB57BB0CC439B2997B01419BD92F80A`
* **Stewart X Addison** <<[email protected]>>
`655F3B5C1FB3FA8D1A0CA6BDE4A7D232B936D2FD`
* **Ulises Gascón** <<[email protected]>>
`A363A499291CBBC940DD62E41F10027AF002F8B0`

Expand All @@ -802,6 +804,7 @@ gpg --keyserver hkps://keys.openpgp.org --recv-keys 8FCCA13FEF1D0C2E91008E09770F
gpg --keyserver hkps://keys.openpgp.org --recv-keys 890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 # Rafael Gonzaga
gpg --keyserver hkps://keys.openpgp.org --recv-keys C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C # Richard Lau
gpg --keyserver hkps://keys.openpgp.org --recv-keys 108F52B48DB57BB0CC439B2997B01419BD92F80A # Ruy Adorno
gpg --keyserver hkps://keys.openpgp.org --recv-keys 655F3B5C1FB3FA8D1A0CA6BDE4A7D232B936D2FD # Stewart X Addison
gpg --keyserver hkps://keys.openpgp.org --recv-keys A363A499291CBBC940DD62E41F10027AF002F8B0 # Ulises Gascón
```

Expand Down
15 changes: 15 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,21 @@ the community they pose.
responsibility to properly handle errors by attaching appropriate
`'error'` event listeners to EventEmitters that may emit errors.

#### Exceptions Thrown by Application Callbacks (CWE-248)

* Node.js trusts the application code it is asked to run, including callbacks
that are invoked by Node.js APIs. If an application callback throws an
uncaught exception, any resulting crash is not considered a vulnerability in
Node.js.
* For example, [CVE-2026-21637](https://www.cve.org/CVERecord?id=CVE-2026-21637)
was triaged as a Node.js vulnerability, but scenarios that require TLS
callbacks such as `ALPNCallback`, `SNICallback`, or `pskCallback` to throw
are outside the Node.js threat model. Future reports of similar issues,
where the crash depends on application callbacks throwing uncaught
exceptions, will not be treated as Node.js vulnerabilities. It is the
application's responsibility to handle unexpected callback input and report
errors without throwing uncaught exceptions.

#### Permission Model Boundaries (`--permission`)

The Node.js [Permission Model](https://nodejs.org/api/permissions.html)
Expand Down
39 changes: 39 additions & 0 deletions benchmark/child_process/child-process-exec-maxbuffer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';
const common = require('../common.js');
const { execFile } = require('child_process');

// Isolates stdout accumulation + maxBuffer handling in execFile(). The child
// writes `chunks` blocks of 64 KiB; the parent accumulates them through the
// native pipe read path and the JS buffering in lib/child_process.js until the
// process exits and the result buffer is handed to the callback.

const bench = common.createBenchmark(main, {
// Number of 64 KiB blocks written by the child: 1 MiB, 16 MiB, 64 MiB.
chunks: [16, 256, 1024],
n: [10],
});

function main({ n, chunks }) {
const script =
'const b = Buffer.alloc(65536, 0x61);' +
`for (let i = 0; i < ${chunks}; i++) process.stdout.write(b);`;
const args = ['-e', script];
const options = {
maxBuffer: chunks * 65536 + 65536,
encoding: 'buffer',
};

let left = n;
const run = () => {
execFile(process.execPath, args, options, (err) => {
if (err)
throw err;
if (--left === 0)
return bench.end(n);
run();
});
};

bench.start();
run();
}
47 changes: 47 additions & 0 deletions benchmark/child_process/child-process-ipc-roundtrip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';
if (process.argv[2] === 'child') {
// Echo every message straight back to the parent.
process.on('message', (msg) => {
process.send(msg);
});
} else {
const common = require('../common.js');
const bench = common.createBenchmark(main, {
len: [64, 256, 1024, 4096, 16384, 65536],
serialization: ['json', 'advanced'],
dur: [5],
});
const { spawn } = require('child_process');

function main({ dur, len, serialization }) {
const msg = { payload: '.'.repeat(len) };
const options = {
stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
serialization,
};
const child = spawn(process.argv[0],
[process.argv[1], 'child'], options);

let messages = 0;
let finished = false;

child.on('message', () => {
messages++;
// Keep one round-trip in flight per completed one so both the serialize
// (write) and deserialize (read) paths stay saturated on both ends.
if (!finished)
child.send(msg);
});

bench.start();
// Prime a window of in-flight messages so the IPC channel never drains.
for (let i = 0; i < 256; i++)
child.send(msg);

setTimeout(() => {
finished = true;
bench.end(messages);
child.kill();
}, dur * 1000);
}
}
43 changes: 43 additions & 0 deletions benchmark/child_process/child-process-spawn-options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';
const common = require('../common.js');
const { spawn } = require('child_process');

// Isolates the cost of marshaling spawn() options across the JS -> C++ boundary
// (ProcessWrap::Spawn). A trivial, fast-exiting child is spawned repeatedly
// while scaling the number of environment pairs and arguments that have to be
// converted, so the per-spawn option-handling overhead is the dominant cost.

const isWindows = process.platform === 'win32';
const command = isWindows ? 'cmd' : 'true';
const baseArgs = isWindows ? ['/d', '/s', '/c', 'exit'] : [];

const bench = common.createBenchmark(main, {
n: [1000],
envc: [0, 64, 256, 1024],
argc: [0, 8, 64],
});

function main({ n, envc, argc }) {
const env = { ...process.env };
for (let i = 0; i < envc; i++)
env[`NODE_BENCH_VAR_${i}`] = `value_${i}`;

const args = baseArgs.slice();
for (let i = 0; i < argc; i++)
args.push(`arg_${i}`);

const options = { env, stdio: ['ignore', 'ignore', 'ignore'] };

let left = n;
const go = () => {
if (--left < 0)
return bench.end(n);
const child = spawn(command, args, options);
// The exit code is intentionally ignored: the child only exercises the
// option-marshaling path, it is not expected to do any useful work.
child.on('exit', go);
};

bench.start();
go();
}
24 changes: 24 additions & 0 deletions benchmark/crypto/create-hmac.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

const common = require('../common.js');
const { createHmac } = require('crypto');
const assert = require('assert');

const bench = common.createBenchmark(main, {
n: [1e5],
algo: ['sha1', 'sha256', 'sha512'],
keylen: [0, 16, 64, 1024],
});

function main({ n, algo, keylen }) {
const key = Buffer.alloc(keylen, 'k');
const hmacs = new Array(n);

bench.start();
for (let i = 0; i < n; ++i) {
hmacs[i] = createHmac(algo, key);
}
bench.end(n);

assert.strictEqual(typeof hmacs[n - 1], 'object');
}
Loading
Loading