Commit Graph
408 Commits
Author SHA1 Message Date
Chris Tate 03af6fb9ff Iterate classes with object-literal iterators and close them on early exits (#1860) 2026-10-24 20:30:36 -05:00
Chris Tate d6c09279a7 Compile createRequire probes for optional addons as deferred refusals (#2015) 2026-10-24 18:41:05 -05:00
Chris Tate 9e55835014 Compile more npm and CommonJS JavaScript dependencies statically (#2122) 2026-10-24 18:30:56 -05:00
Chris Tate 29e5bacb9c Pump untyped iterable pipeline sources (#2111) 2026-10-24 18:03:36 -05:00
Chris Tate 055c9ffa25 Evaluate the arguments of deferred require.resolve calls before they throw
Preflight admits a createRequire loader's require.resolve call with a
computed request inside a try block, but lowering refused the call, so
in JavaScript source the whole statement became a runtime fence. The
fence threw before the request expression ran, and before anything else
in the statement: `try { where = load.resolve(candidate(name)); }`
skipped candidate()'s side effects, so the catch clause saw a different
state than in Node.

Such calls (a computed request, another argument shape, or
runtime-computed options, on require.resolve and require.resolve.paths)
now evaluate their arguments in order and then throw the fence, as a
computed require call does. The addon-probe fixture checks that a
computed candidate path runs before each failed lookup.
2026-10-24 17:07:44 -05:00
Chris Tate 8d9705e22d Run CommonJS top-level return, untyped assert forms, and untyped instanceof Object as Node does (#2101) 2026-10-24 17:01:39 -05:00
Chris Tate c37963b8aa Let objects inherit from JavaScript class prototypes (#2078) 2026-10-24 16:58:49 -05:00
Chris Tate 6a8ba89d9f Make Dates mutable objects with Node's setters and conversions (#2072) 2026-10-24 16:21:06 -05:00
Chris Tate 4f0975cbbe Compile more npm and CommonJS JavaScript dependencies statically 2026-10-24 12:01:26 -05:00
Chris Tate 53baad4ebe Pump untyped iterable pipeline sources
A pipeline whose first stage is a checked-dynamic value now checks it at
run time, as Node's stage ladder does: a stream is piped as before, and a
string or a value with a Symbol.asyncIterator or Symbol.iterator method is
pumped into the next stage through an async generator over its iterator.
A typed Set, Map, generator or async generator object as the first stage
takes the same path. This covers the callback and stream/promises forms,
with or without function stages and pipeline options.

A write whose callback fails synchronously no longer sets needDrain, so no
'drain' follows the error and a pumped source stops at the failed write,
as in Node.

RUNTIME_ABI_VERSION goes from 37 to 42 for scr_stream_dyn_iterable_source.
2026-10-24 10:12:06 -05:00
Chris Tate d9f1457cd5 Run CommonJS top-level return, untyped assert forms, and untyped instanceof Object as Node does 2026-10-24 08:07:52 -05:00
Chris Tate ead125a5c5 Merge main 2026-10-24 06:47:32 -05:00
Chris Tate 0f90e07603 Process non-ASCII URL hosts with UTS #46 as Node does (#2088) 2026-10-24 02:48:24 -05:00
Chris Tate 1e90263517 Support Symbol.toStringTag class fields and getters (#2037) 2026-10-24 01:21:32 -05:00
Chris Tate 20339d9c27 Process non-ASCII URL hosts with UTS #46 as Node does 2026-10-24 01:13:00 -05:00
Chris Tate 7bf50dd9cc zlib: Brotli compression and decompression over the vendored brotli 1.2.0 (#2053) 2026-10-24 00:30:21 -05:00
Chris Tate 3b951ef4e2 Let objects inherit from JavaScript class prototypes 2026-10-23 23:43:30 -05:00
Chris Tate fe3fd0de44 Parse URL hosts and paths as the URL Standard does, and inspect URLs as Node does (#2071) 2026-10-23 23:38:03 -05:00
Chris Tate 5c131cba35 Report dictionary copies of {} views, and keep method calls direct after writes into dictionaries of dictionaries (#1855) 2026-10-23 22:18:05 -05:00
Chris Tate 27593e366e Make Dates mutable objects with Node's setters and conversions 2026-10-23 22:08:02 -05:00
Chris Tate 52e84ad3b4 Parse URL hosts and paths as the URL Standard does, and inspect URLs as Node does 2026-10-23 21:57:53 -05:00
Chris Tate c9346c1583 Merge main 2026-10-23 21:51:54 -05:00
Chris Tate 0f75f5b952 Keep the run-time result of overloaded calls with untyped arguments
The checker resolves an overloaded call whose argument is `any` to the
first overload that argument satisfies, but in JavaScript the value can
select another one: generateKeyPairSync("ec", options) returns KeyObjects
or PEM strings by the options, and digest(encoding) returns a Buffer when
the encoding is undefined. The result was converted to the first
overload's return type, so such calls threw a TypeError where Node
returns the other overload's value.

When a checked-dynamic argument could take another overload whose return
type differs (trailing untyped or undefined arguments may also be
absent), the call's result in a JavaScript source is checked-dynamic. So
are the unannotated bindings it initializes, destructured or not, and
the unannotated functions that return it. fs.globSync keeps choosing its
result form from the resolved overload, since the runtime checks that
withFileTypes agrees with it.
2026-10-23 20:31:12 -05:00
Chris Tate cc325de274 Merge main 2026-10-23 19:24:16 -05:00
Chris Tate 9adb9692cd Accept file URL paths in existsSync and fs.promises (#2042) 2026-10-23 18:47:49 -05:00
Chris Tate a9da37b82e zlib: Brotli compression and decompression over the vendored brotli 1.2.0 2026-10-23 18:11:49 -05:00
Chris Tate b09d5c6862 Merge main 2026-10-23 17:43:25 -05:00
Chris Tate 7f8b0c2a09 Support X25519 keys and crypto.diffieHellman (#2039) 2026-10-23 17:23:19 -05:00
Chris Tate 7230b14f9d Represent Dates as objects with identity (#1915) 2026-10-23 16:49:26 -05:00
Chris Tateandjlucaso1 0b83599af4 Accept file URL paths in existsSync, fs.promises and order-checked fs calls
existsSync and the fs.promises functions accept a file: URL wherever
they accept a path. They convert it after their arguments are evaluated,
and a URL that does not convert gives false from existsSync and a promise
rejected with fileURLToPath's error from fs.promises, as in Node.

copyFileSync and renameSync check a string source for null bytes before
they convert a URL destination, and readFileSync checks a runtime
encoding before it converts a URL path, so the error Node reports first
is the one thrown.

Refs #1616

Co-authored-by: jlucaso1 <55464917+jlucaso1@users.noreply.github.com>
2026-10-23 16:27:40 -05:00
Chris Tate fc229822e7 Support X25519 keys and crypto.diffieHellman
X25519 KeyObjects come from generateKeyPair(Sync)("x25519"), which keeps
the private key clamped as OpenSSL does, and from createPrivateKey and
createPublicKey of PKCS#8, SubjectPublicKeyInfo, JWK (OKP, X25519) and
raw keys. They export in the same forms. sign, verify, createSign and
createVerify throw OpenSSL's "operation not supported for this keytype",
with its library, reason and code properties. X25519 uses mbedTLS's
Curve25519 group.

crypto.diffieHellman({ privateKey, publicKey }[, callback]) computes the
X25519 and ECDH secrets of two keys of one type, given as KeyObjects or
in any form createPrivateKey and createPublicKey read. The checks run in
Node's order: the options, the callback, both keys present, the key types
when both are KeyObjects ("Incompatible key types for Diffie-Hellman"),
then the public and private key inputs. Mismatched curves, a small-order
X25519 point and key types other than EC and X25519 throw OpenSSL's
errors. The callback form passes the secret, or the error without the
OpenSSL properties, in a later macrotask, as Node's DHBitsJob does.

createPublicKey also reads a private key's DER encodings (pkcs8 and
sec1), which Node accepts there.
2026-10-23 15:56:08 -05:00
Chris Tate e7943984a5 Bind both Dates before comparing, and cache only new Date locals as time values 2026-10-23 15:50:09 -05:00
Chris Tate e0d0e03eed Support Symbol.toStringTag class fields and getters 2026-10-23 15:47:49 -05:00
Chris Tate 9a2d378fba Run completion callbacks in their call's AsyncLocalStorage context (#1804) 2026-10-23 15:29:35 -05:00
Chris Tate 850710fbea Box TextEncoder and TextDecoder records as checked-dynamic handles (#2022) 2026-10-23 15:03:43 -05:00
Chris Tate 96a5954940 Merge main 2026-10-23 14:09:13 -05:00
Chris Tate 693e33742a Support the raw-public and raw-private key formats
EC and Ed25519 keys read and write Node 24's raw formats:

- generateKeyPair(Sync) encodings: raw-public gives the EC point,
  uncompressed or, with type "compressed", compressed, or the Ed25519
  public key; raw-private gives the EC scalar at the curve's size or the
  Ed25519 seed.
- KeyObject.export({ format: "raw-public" | "raw-private" | "raw-seed" }),
  with Node's check of the point type, and Node's error for a passphrase
  with any format other than PEM and DER, which now also covers JWK.
- createPublicKey and createPrivateKey of { key, format,
  asymmetricKeyType, namedCurve }, in Node's argument order, with
  compressed EC points, and createPublicKey of a raw private key.

As in Node, raw-seed and every raw format of an RSA, RSA-PSS, DSA or DH
key throw ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS, which generateKeyPair
passes to its callback. Invalid key data throws ERR_INVALID_ARG_VALUE.
Raw X25519, X448, Ed448 and post-quantum keys, EC scalars of 0 or at
least the curve order, and the EC point at infinity, which Node accepts,
throw a coded SC2020 error.
2026-10-23 13:59:28 -05:00
Chris Tate 08f282e1b6 Merge main and run finish, close and pipeline callbacks in their AsyncLocalStorage context 2026-10-23 13:57:55 -05:00
Chris Tate 47636f2fa5 Implement the identity TransformStream natively (#2009) 2026-10-23 13:51:52 -05:00
Malte UblandClaude Opus 5.5 f14997776b Box TextEncoder and TextDecoder records as checked-dynamic handles
A codec stored in untyped storage (hono's StreamingApi keeps
`this.encoder = new TextEncoder()` in a JavaScript class field) had no
dynamic representation and threw SC1101 at run time. The codec records
now cross 'unknown' slots as handles of two new tags that hold the record
itself, so identity and a decoder's streaming state survive the round
trip, and checked casts unbox the same record.

The handles answer encode, encodeInto and decode (with options objects),
the encoding, fatal and ignoreBOM properties, method values with Node's
ERR_INVALID_THIS, instanceof, String() tags and JSON's {}. The unit
scr_text_codec_dyn.c links only into programs that convert a codec to or
from an untyped value (the textCodecDyn runtime feature, found with the
dgram carrier walk, now shared).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 10:33:06 -07:00
Chris Tate d10ddff548 Compile createRequire probes for optional addons as deferred refusals
Packages such as pi-tui look for their prebuilt Node-API addons at run
time: a createRequire require call with a computed path, and the
loader's resolve passed as a value, each inside a try block whose catch
takes a fallback. Preflight refused these packages.

Preflight now classifies each use of a createRequire loader. Inside the
try block of a try statement in the same function, a call with a
computed specifier or another argument shape, and resolve or
resolve.paths read as a value, no longer refuse the package. Outside a
try block they keep it refused, with a reason that names the computed
specifier. The loader itself as a value, writes and optional calls stay
refused.

In JavaScript source, such a call evaluates its arguments and then
throws a runtime fence, and the resolve value is a function that throws
one when called, so `(options.resolve ?? require.resolve)(id)` still
calls the option. Both are listed in coverage as deferred to runtime.
TypeScript source keeps the compile-time refusals.

Refs #1777
2026-10-23 11:36:23 -05:00
Malte UblandClaude Opus 5.5 3c2911ccad Implement the identity TransformStream natively
'new TransformStream()' had no lowering, so hono's stream() and
streamSSE() helpers failed to compile their checked-dynamic paths. The
constructor without arguments now builds a native handle: its readable
side is a native ReadableStream with a zero high-water mark, and its
writable side runs the streams spec's WritableStream state machine
(getWriter, abort, close, locked; the writer's write, close, abort,
releaseLock, ready, closed and desiredSize). A write completes when the
readable side reads its chunk, close/abort/cancel propagate across the
pair, and deferred reactions take as many microtask turns as in Node.
Web ReadableStreams can also be weak collection keys (hono keys a
WeakMap by the response stream). A transformer, queuing strategies and
the WritableStream constructor keep the SC2020 refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 08:47:47 -07:00
Chris Tate 313eb1177c Merge main and fix CI 2026-10-23 09:14:31 -05:00
Chris Tate 1221104388 Merge main and fix CI 2026-10-23 07:50:09 -05:00
Chris Tate ad33563c44 Merge main 2026-10-23 05:57:14 -05:00
Chris Tate 8d17fe4e57 Support crypto.getCipherInfo, AES-CCM and AES key wrap (#1873) 2026-10-23 05:36:21 -05:00
Chris Tate 19e0fe8bcd Merge main and read cipher options through getters and prototypes 2026-10-23 05:33:14 -05:00
Chris Tate 945a519036 Match Node for typed pipeline callbacks and rl.cursor on non-terminal interfaces 2026-10-23 03:49:51 -05:00
Chris Tate 91e15f3426 Run child_process and http2 events in Node's AsyncLocalStorage contexts
child_process and http2 events ran with no store, or with the context of
whichever socket dispatch delivered them. Node runs them in the context
of the handle or request that produces them.

child_process: a child, its piped stdout, stderr and stdin, and its IPC
channel keep the context of the spawn() or fork() call. 'spawn',
'error', 'exit', 'close', stdout's and stderr's 'data' and 'end', and the
channel's 'message' and 'disconnect' run in it, in the POSIX and the
Windows implementations. stdin's 'drain' and 'error' run in the context
of the latest write() call, its 'finish' in the context of its end()
call, and a send() callback in the context of its send() call.

http2: a session keeps the context it was created in, the
http2.connect() call for a client and the server's listen() context for
a server session, and the session's socket callbacks and deferred emits
run in it. A client stream keeps the context of its request() call, and
the frames that drive a stream's events (DATA, WINDOW_UPDATE, RST_STREAM,
and a client's HEADERS) and its deferred emits run in the stream's
context. A session remembers the stream its last lookup by id found, so
the context lookup and the frame's own handling share one search.
A server stream and its compatibility request and response run with no
store, as Node's do. An accepted h2c socket's own events run with no
store, as an accepted net socket's do, so a server.close() that waits for
its sessions calls back with no store; a TLS server's sockets keep the
listen() context, as before.

Corpus 7385 to 7389.
2026-10-23 03:40:52 -05:00
Chris Tate 8bb9ee8c57 Check generateKeyPair arguments and RSA parameters as Node does 2026-10-23 03:38:18 -05:00