Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ in-app, with npm modules and N-API native addons.
| Android | `libnode.so` + headers | `arm64-v8a`, `armeabi-v7a`, `x86_64` (16 KB page size) |
| iOS | `NodeMobile.xcframework` | `arm64` device, `arm64` simulator |

Current line: **Node.js 24 LTS**, previewing the `v24.22.0` release proposal
[#66667](https://github.com/nodejs/node/pull/66667) at a fixed commit. The
official upstream tag is not published yet. `process.version` reports the
Current line: **Node.js 24 LTS** (`v24.22.1`, official security release).
The pin is the official tag `v24.22.1` at commit
`ce7aaf1cee78b8cf0ce17364260535c418d3ed26`. `process.version` reports the
upstream version unchanged, so version-parsing tools keep working; the
mobile build is identified by `process.versions.mobile` (`"24.22.0-0"`).
See [the 24.22 preview notes](docs/UPSTREAM-24.22.md) for source provenance.
mobile build is identified by `process.versions.mobile` (`"24.22.1-0"`).
See [the 24.22 line notes](docs/UPSTREAM-24.22.md) for source provenance.

## Maintained version lines

| Branch | Node.js base | Purpose |
| --- | --- | --- |
| [`recipe`](https://github.com/fogtape/nodejs-mobile/tree/recipe) | 24.22.0 proposal | Node 24 LTS maintenance and CI previews |
| [`recipe`](https://github.com/fogtape/nodejs-mobile/tree/recipe) | 24.22.1 (official tag) | Node 24 LTS maintenance and CI previews |
| [`recipe-v26`](https://github.com/fogtape/nodejs-mobile/tree/recipe-v26) | 26.1.0 | Independent Node 26 port and CI previews |

Each branch owns its upstream tag, patches, source-tree checksum and toolchain.
Expand Down
37 changes: 37 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
</tr>
<tr>
<td>
<a href="#24.22.1-0">24.22.1-0</a><br/>
<a href="#24.22.0-0">24.22.0-0</a><br/>
<a href="#24.21.0-0">24.21.0-0</a><br/>
<a href="#24.20.0-0">24.20.0-0</a><br/>
Expand Down Expand Up @@ -40,6 +41,42 @@
</tr>
</table>

<a id="24.22.1-0"></a>
## 2026-10-21, Version 24.22.1-0 (Current)

- Move off the 24.22.0 release-proposal snapshot to the official Node.js
`v24.22.1` security release
(`ce7aaf1cee78b8cf0ce17364260535c418d3ed26`). The reviewed proposal commit
differs from the published `v24.22.0` tag only in
`doc/changelogs/CHANGELOG_V24.md`. The rebase re-emitted 20 patches; only
`common.gypi` and the mobile adjustment in `src/crypto/crypto_context.cc`
changed, and only in context/line numbers.
- Pick up upstream's seven CVE fixes for this line: tls IP normalization and
non-canonical IP addresses, dns resolve null bytes, the http agent data
guard, the permission model in `realpathSync`, crypto snapshot random
caches and brotli block-switch decoding. Also carry OpenSSL 3.5.9,
c-ares 1.34.9, undici 7.30.1, tzdata 2026e, root certificates NSS 3.131.1
and the rejection of certificate chains with blocked public keys.
- Exclude the new `test-crypto-random-cache-snapshot` regression on Android
and iOS: it builds and runs snapshots through `common/snapshot`, which
spawns child Node executables. The remaining new in-process regressions
(tls non-canonical IP and SPKI blocklist, dns null bytes, http agent
pending read, X.509 name conversion) stay runnable; the full device suite
confirms them.
- Run `test-crypto-x509`'s malformed-certificate legacy conversion in-process
on Android and iOS instead of in a child Node. Upstream added the child to
report a native regression as a signal; an app cannot spawn one (Android's
`process.execPath` is `app_process`, which aborts with "Error changing
dalvik-cache ownership : Permission denied"). The same conversion and
assertions run in-process, and a native abort still fails the run through
the harness crash verdict.
- Runtime and flavor configuration is unchanged: complete ICU API, the
reviewed danmu lite data profile, Android JIT/native WebAssembly and
pointer compression, iOS jitless V8 with polywasm.
- This source upgrade does not itself publish. `release-ready.txt` and
`release-upstream-snapshot.txt` are left empty: an official tag now backs
the line, and arming a version is the reviewed Cut release step.

<a id="24.22.0-0"></a>
## 2026-10-13, Version 24.22.0-0 (Current)

Expand Down
2 changes: 1 addition & 1 deletion docs/UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The upgrade builds both Android/iOS flavors, runs the full device gates and
packages versioned CI previews. Cut release and publication require an
official upstream tag on this line. Once the tag exists, compare it against
the pinned proposal, update the pin, regenerate and rerun the gates.
See [the Node 24.22 proposal](UPSTREAM-24.22.md) and the current
See [the Node 24.22 line notes](UPSTREAM-24.22.md) and the current
[manual release procedure](RELEASING.md).

## Re-base the series
Expand Down
55 changes: 37 additions & 18 deletions docs/UPSTREAM-24.22.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
# Node 24.22 LTS upstream PR preview

This recipe previews the official Node.js release proposal
[#66667](https://github.com/nodejs/node/pull/66667), titled
`2026-10-14, Version 24.22.0 'Krypton' (LTS)`. On 2026-10-13 it is still a
draft PR, with no official `v24.22.0` tag.

The reviewed baseline is pinned in `upstream-base.txt`:
`a5d0eb95dd03b90986ad1a7c0cd3f2de1a0f383c`.
The upstream header identifies Node 24.22.0 and the mobile header identifies
24.22.0-0. Those version strings identify the proposed source; they do not
mean that the upstream release has been published. The immutable commit and
`expected-tree.txt` identify the build if the proposal branch changes.
# Node 24.22 LTS upstream line

`upstream-base.txt` pins the official tag `v24.22.1`
(`ce7aaf1cee78b8cf0ce17364260535c418d3ed26`), upstream's security release
for this line. It replaces the reviewed release-proposal snapshot of
[#66667](https://github.com/nodejs/node/pull/66667), pinned at
`a5d0eb95dd03b90986ad1a7c0cd3f2de1a0f383c`. That proposal was published as
`v24.22.0` on 2026-10-14, and its commit differs from the reviewed snapshot
only in `doc/changelogs/CHANGELOG_V24.md`.

The mobile header now reports `24.22.1-0`, and `expected-tree.txt` records
the rebuilt product tree. The rebase re-emitted 20 patches; only two changed
and only in context/line numbers — `common.gypi` (`v8_embedder_string`) and
the mobile adjustment in `src/crypto/crypto_context.cc`, whose upstream
X.509 hardening lands ahead of the mobile hunks. The mobile hunks themselves
are unchanged.

The release carries upstream's security fixes for the line: seven CVEs
covering tls IP normalization and non-canonical IP addresses, dns resolve
null bytes, the http agent data guard, the permission model in
`realpathSync`, crypto snapshot random caches and brotli block-switch
decoding. It also updates OpenSSL to 3.5.9, c-ares to 1.34.9, undici to
7.30.1, tzdata to 2026e and the root certificates to NSS 3.131.1, and
rejects certificate chains containing blocked public keys.

## Lite configuration

Expand Down Expand Up @@ -197,8 +208,16 @@ The updated harness is included in source tree

## Move to the official release

After upstream publishes `v24.22.0`, compare its commit with this baseline,
review any differences, update `upstream-base.txt`, regenerate the recipe and
checksum, and rerun platform/device validation. Follow
[RELEASING.md](RELEASING.md) for reviewed version selection and explicit
publication. A source upgrade or ordinary build does not publish by itself.
This branch performed the move: it pins `v24.22.1`, the security release
that followed the reviewed proposal. The proposal commit was compared with
the published `v24.22.0` tag first — the two trees differ only in
`doc/changelogs/CHANGELOG_V24.md` — and the recipe was then rebased onto
`v24.22.1`, regenerated and re-verified.

The procedure, retained for the record: after upstream publishes a release,
compare its commit with the pin, review any differences, update
`upstream-base.txt` to the official tag, regenerate the recipe and checksum,
and rerun platform/device validation. Default Cut release and publication
reject SHA baselines; follow [RELEASING.md](RELEASING.md) for reviewed
version selection and explicit publication. A source upgrade or ordinary
build does not publish by itself.
2 changes: 1 addition & 1 deletion expected-tree.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
# run prepare.sh (or regenerate-patches.py, which prints the hash) and
# update the value below in the same commit. If you forget, CI fails and
# prints the hash it got.
786da7b5d33a6cabb31668f3089731b3c0a62713
59a1f9b50b39080936dc0e78838b3945da83d8e0
2 changes: 1 addition & 1 deletion mobile-src/src/node_mobile_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#define NODE_MOBILE_MAJOR_VERSION 24
#define NODE_MOBILE_MINOR_VERSION 22
#define NODE_MOBILE_PATCH_VERSION 0
#define NODE_MOBILE_PATCH_VERSION 1

// Mobile rebuild revision of the same upstream Node version: the -R in the
// vX.Y.Z-R release tag. Computed and bumped by the Cut release workflow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Co-authored-by: João Matos <joao@tritao.eu>
1 file changed, 118 insertions(+), 7 deletions(-)

diff --git a/common.gypi b/common.gypi
index bc690955d3..b3a74cb587 100644
index b416129334..ad5d99fb7f 100644
--- a/common.gypi
+++ b/common.gypi
@@ -115,7 +115,7 @@
Expand Down
1 change: 1 addition & 0 deletions patches/files.map
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ test-mobile-test-harness.patch test/message/message.status
test-mobile-test-harness.patch test/message/testcfg.py
test-mobile-test-harness.patch tools/test.py
test-skip-adapt-parallel-and-sequential-tests-for-mo.patch test/parallel/parallel.status
test-skip-adapt-parallel-and-sequential-tests-for-mo.patch test/parallel/test-crypto-x509.js
test-skip-adapt-parallel-and-sequential-tests-for-mo.patch test/parallel/test-dgram-bind-fd.js
test-skip-adapt-parallel-and-sequential-tests-for-mo.patch test/parallel/test-dgram-membership.js
test-skip-adapt-parallel-and-sequential-tests-for-mo.patch test/parallel/test-dgram-socket-buffer-size.js
Expand Down
10 changes: 5 additions & 5 deletions patches/src-crypto-mobile-adjustment-in-crypto_context.cc.patch
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ Co-authored-by: Julia Samól <j.samol@papers.ch>
1 file changed, 17 insertions(+)

diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index 74ea622dad..575cbb51ff 100644
index 71debb0805..a3ad327890 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -336,6 +336,9 @@ bool isSelfIssued(X509* cert) {
@@ -341,6 +341,9 @@ bool isSelfIssued(X509* cert) {
#ifdef __APPLE__
TrustStatus IsTrustDictionaryTrustedForPolicy(CFDictionaryRef trust_dict,
bool is_self_issued) {
Expand All @@ -32,7 +32,7 @@ index 74ea622dad..575cbb51ff 100644
// Trust settings may be scoped to a single application
// skip as this is not supported
if (CFDictionaryContainsKey(trust_dict, kSecTrustSettingsApplication)) {
@@ -427,6 +430,10 @@ TrustStatus IsTrustDictionaryTrustedForPolicy(CFDictionaryRef trust_dict,
@@ -432,6 +435,10 @@ TrustStatus IsTrustDictionaryTrustedForPolicy(CFDictionaryRef trust_dict,
return (trust_settings_result == kSecTrustSettingsResultTrustAsRoot)
? TrustStatus::TRUSTED
: TrustStatus::UNSPECIFIED;
Expand All @@ -43,7 +43,7 @@ index 74ea622dad..575cbb51ff 100644
}

TrustStatus IsTrustSettingsTrustedForPolicy(CFArrayRef trust_settings,
@@ -498,6 +505,8 @@ bool IsCertificateTrustedForPolicy(X509* cert, SecCertificateRef ref) {
@@ -503,6 +510,8 @@ bool IsCertificateTrustedForPolicy(X509* cert, SecCertificateRef ref) {
bool trust_evaluated = false;
bool is_self_issued = isSelfIssued(cert);

Expand All @@ -52,7 +52,7 @@ index 74ea622dad..575cbb51ff 100644
// Evaluate user trust domain, then admin. User settings can override
// admin (and both override the system domain, but we don't check that).
for (const auto& trust_domain :
@@ -536,6 +545,14 @@ bool IsCertificateTrustedForPolicy(X509* cert, SecCertificateRef ref) {
@@ -541,6 +550,14 @@ bool IsCertificateTrustedForPolicy(X509* cert, SecCertificateRef ref) {
CFRelease(trust_settings);
}
}
Expand Down
83 changes: 79 additions & 4 deletions patches/test-skip-adapt-parallel-and-sequential-tests-for-mo.patch
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ series itself.
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
Co-authored-by: Andre Staltz <andre@staltz.com>
---
test/parallel/parallel.status | 1511 +++++++++++++++++
test/parallel/parallel.status | 1519 +++++++++++++++++
test/parallel/test-crypto-x509.js | 55 +-
test/parallel/test-dgram-bind-fd.js | 2 +-
test/parallel/test-dgram-membership.js | 10 +-
.../parallel/test-dgram-socket-buffer-size.js | 2 +-
Expand Down Expand Up @@ -55,13 +56,13 @@ Co-authored-by: Andre Staltz <andre@staltz.com>
test/sequential/sequential.status | 132 ++
test/sequential/test-async-wrap-getasyncid.js | 15 +-
test/sequential/test-fs-watch.js | 4 +
39 files changed, 1834 insertions(+), 51 deletions(-)
40 files changed, 1876 insertions(+), 72 deletions(-)

diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status
index d13efc8ac1..fccf6d71a2 100644
index d13efc8ac1..61a2c70d1f 100644
--- a/test/parallel/parallel.status
+++ b/test/parallel/parallel.status
@@ -160,6 +160,1517 @@ test-tls-set-default-ca-certificates-append-fetch: SKIP
@@ -160,6 +160,1525 @@ test-tls-set-default-ca-certificates-append-fetch: SKIP
test-tls-set-default-ca-certificates-reset-fetch: SKIP
test-inspector-invalid-protocol: SKIP

Expand Down Expand Up @@ -119,6 +120,10 @@ index d13efc8ac1..fccf6d71a2 100644
+test-coverage-with-inspector-disabled: SKIP
+test-crypto-fips: SKIP
+test-crypto-provider-cache-snapshot: SKIP
+# Added by the v24.22.1 security rebase: the new snapshot regression builds
+# and runs snapshots through common/snapshot, which spawns child Node
+# executables (the same limitation as the entry above).
+test-crypto-random-cache-snapshot: SKIP
+test-crypto-secure-heap: SKIP
+test-cwd-enoent*: SKIP
+test-debug-usage: SKIP
Expand Down Expand Up @@ -790,6 +795,10 @@ index d13efc8ac1..fccf6d71a2 100644
+test-crypto-fips: SKIP
+test-crypto-no-algorithm: SKIP
+test-crypto-provider-cache-snapshot: SKIP
+# Added by the v24.22.1 security rebase: the new snapshot regression builds
+# and runs snapshots through common/snapshot, which spawns child Node
+# executables (the same limitation as the entry above).
+test-crypto-random-cache-snapshot: SKIP
+test-crypto-secure-heap: SKIP
+test-cwd-enoent*: SKIP
+test-debug-usage: SKIP
Expand Down Expand Up @@ -1579,6 +1588,72 @@ index d13efc8ac1..fccf6d71a2 100644
[$asan==on]
# https://github.com/nodejs/node/issues/39655
test-cluster-primary-error: PASS, FLAKY
diff --git a/test/parallel/test-crypto-x509.js b/test/parallel/test-crypto-x509.js
index 8e8ae2773d..b02fe84c48 100644
--- a/test/parallel/test-crypto-x509.js
+++ b/test/parallel/test-crypto-x509.js
@@ -498,27 +498,40 @@ UcXd/5qu2GhokrKU2cPttU+XAN2Om6a0
if (!isBoringSSL) {
const cert = new X509Certificate(certPem);

- // Run the legacy conversion in a child so a native regression is reported
- // as a signal rather than terminating the test runner.
- const child = spawnSync(process.execPath, [
- '-e',
- `
- 'use strict';
- const assert = require('node:assert');
- const { X509Certificate } = require('node:crypto');
- const cert = new X509Certificate(process.argv[1]);
- const legacy = cert.toLegacyObject();
- assert.strictEqual(legacy.modulus, undefined);
- assert.strictEqual(legacy.exponent, undefined);
- assert.strictEqual(legacy.pubkey, undefined);
- `,
- '--',
- certPem,
- ], {
- encoding: 'utf8',
- });
- assert.strictEqual(child.signal, null, child.stderr || child.stdout);
- assert.strictEqual(child.status, 0, child.stderr || child.stdout);
+ if (common.isAndroid || common.isIOS) {
+ // nodejs-mobile patch: an app cannot spawn a child Node. Android's
+ // process.execPath is app_process, which aborts with "Error changing
+ // dalvik-cache ownership : Permission denied", and the iOS app has no
+ // executable to spawn either. Run the legacy conversion in-process and
+ // keep the same assertions; a native abort still fails the run through
+ // the crash verdict the harness records.
+ const legacy = cert.toLegacyObject();
+ assert.strictEqual(legacy.modulus, undefined);
+ assert.strictEqual(legacy.exponent, undefined);
+ assert.strictEqual(legacy.pubkey, undefined);
+ } else {
+ // Run the legacy conversion in a child so a native regression is
+ // reported as a signal rather than terminating the test runner.
+ const child = spawnSync(process.execPath, [
+ '-e',
+ `
+ 'use strict';
+ const assert = require('node:assert');
+ const { X509Certificate } = require('node:crypto');
+ const cert = new X509Certificate(process.argv[1]);
+ const legacy = cert.toLegacyObject();
+ assert.strictEqual(legacy.modulus, undefined);
+ assert.strictEqual(legacy.exponent, undefined);
+ assert.strictEqual(legacy.pubkey, undefined);
+ `,
+ '--',
+ certPem,
+ ], {
+ encoding: 'utf8',
+ });
+ assert.strictEqual(child.signal, null, child.stderr || child.stdout);
+ assert.strictEqual(child.status, 0, child.stderr || child.stdout);
+ }

assert.throws(() => cert.publicKey, {
message: hasOpenSSL(3) ? /decode error/ : /wrong tag/,
diff --git a/test/parallel/test-dgram-bind-fd.js b/test/parallel/test-dgram-bind-fd.js
index daf7f8064b..76c2ce82dd 100644
--- a/test/parallel/test-dgram-bind-fd.js
Expand Down
1 change: 0 additions & 1 deletion release-ready.txt
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
24.22.0-0
1 change: 0 additions & 1 deletion release-upstream-snapshot.txt
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
a5d0eb95dd03b90986ad1a7c0cd3f2de1a0f383c
7 changes: 3 additions & 4 deletions upstream-base.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Node.js 24.22.0 LTS release proposal; the official tag is not published yet.
# https://github.com/nodejs/node/pull/66667 (v24.22.0-proposal)
# Pin the reviewed PR commit rather than following the moving proposal branch.
a5d0eb95dd03b90986ad1a7c0cd3f2de1a0f383c
# Node.js 24.22.1 LTS security release.
# https://github.com/nodejs/node/releases/tag/v24.22.1
v24.22.1
Loading