Skip to content

fs: validate copyFile paths in the existing C++ binding - #28

Draft
anonrig wants to merge 59 commits into
mainfrom
cursor/copyfile-unify-68bc
Draft

fs: validate copyFile paths in the existing C++ binding#28
anonrig wants to merge 59 commits into
mainfrom
cursor/copyfile-unify-68bc

Conversation

@anonrig

@anonrig anonrig commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Addresses Matteo’s review on nodejs/node#65376: keep a single binding.copyFile instead of adding copyFileSync.

Review

Then why keep both methods? Can't we just fix copyFile and update all usage of that?

getValidatedPath, file URL conversion, and NUL checks now live in the existing C++ CopyFile binding. The sync, callback, and promises JS entry points all call binding.copyFile with the original arguments. The extra copyFileSync binding is gone.

VFS dispatch still happens in JavaScript before the binding. The copy itself is still uv_fs_copyfile.

The original PR branch cursor/copyfilesync-cpp-upstream-317c was updated with the same commit so nodejs/node#65376 has this change.

Performance

Same-binary comparison of the old JS getValidatedPath + binding.copyFile path vs the unified C++-validated binding.copyFile (n=10000, 9 interleaved repeats, Release v27.0.0-pre):

case old C++ change
valid copy 60.8 µs/op 61.1 µs/op ~same
missing src (ENOENT) 5.52 µs/op 5.39 µs/op ~2% faster
invalid type 8.04 µs/op 3.92 µs/op ~51% faster
file URL 60.0 µs/op 60.2 µs/op ~same

I/O-bound valid / file URL stay within noise of the old path. ENOENT is within a few percent. The win is validation-bound input (wrong type), and because validation is on binding.copyFile, callback and promises get that path too.

benchmark/fs/bench-copyFileSync.js (n=10000) on this binary: valid ~16.1k ops/sec, invalid (ENOENT) ~260k ops/sec.

Testing

cpplint on src/node_file.cc and ESLint on the JS/test changes are clean. A full Node.js rebuild of this revision was used for the numbers above.

Open in Web Open in Cursor 

nodejs-github-bot and others added 30 commits August 14, 2026 18:33
PR-URL: nodejs#65114
Reviewed-By: Chengzhong Wu <[email protected]>
Signed-off-by: ulofiai <[email protected]>
PR-URL: nodejs#65118
Fixes: nodejs#63638
Refs: libuv/libuv#5152
Refs: libuv/libuv@e640dc9
Reviewed-By: Antoine du Hamel <[email protected]>
Signed-off-by: Matteo Collina <[email protected]>
PR-URL: nodejs#65250
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: René <[email protected]>
Reviewed-By: Rafael Gonzaga <[email protected]>
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: Daeyeon Jeong <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Stewart X Addison <[email protected]>
Reviewed-By: Mike McCready <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Reviewed-By: Beth Griggs <[email protected]>
Use undefined as the no-error sentinel when cancelling broadcast and
share consumers. This ensures that 0, an empty string, false, and null
are propagated instead of being converted to clean completion.

Make sync share surface cancellation reasons before handling detached
consumers, and add regression coverage for async and sync consumers.

Signed-off-by: Kamat, Trivikram <[email protected]>
Assisted-by: codex:gpt-5.6-sol
PR-URL: nodejs#64705
Fixes: nodejs#64704
Reviewed-By: James M Snell <[email protected]>
SQLite requires that an authorizer callback not modify the connection
that invoked it, and counts sqlite3_prepare_v2() and sqlite3_step() as
modifications. node:sqlite let the callback call prepare(), exec(), the
statement execution methods, and other connection-mutating APIs on the
same DatabaseSync. Track authorizer depth on DatabaseSync with an RAII
guard around the callback and throw ERR_INVALID_STATE from the affected
entry points while it is on the stack. Covering every authorizer
invocation, including the re-prepare that SQLite can run during
sqlite3_step(), exposed a second and distinct hazard: reentering a
statement that is currently being stepped is a use-after-free rather
than a contract violation, since finalizing it frees the virtual machine
under sqlite3_step() and re-running it resets that machine
mid-execution. Any callback SQLite invokes during execution can reach
it, so a user-defined function is enough. Track the statements currently
being stepped and reject reentry into only those, which leaves a
user-defined function free to prepare, run, and finalize its own helper
statements.

Signed-off-by: Trevor Burnham <[email protected]>
Fixes: nodejs#63207
Assisted-by: claude:opus-5
PR-URL: nodejs#65156
Reviewed-By: Xuguang Mei <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Signed-off-by: Guilherme Araújo <[email protected]>
PR-URL: nodejs#62757
Reviewed-By: Xuguang Mei <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Reviewed-By: Edy Silva <[email protected]>
Replace the async generator backing Symbol.asyncIterator with a
hand-rolled iterator. The generator machinery costs several extra
promise allocations and microtask hops per chunk: yield awaits the
yielded value and resolves the pending request through separate
promises. Buffered chunks are now delivered as an already-resolved
promise, one microtask sooner than before.

Thenable chunks are still awaited before delivery, requests received
while a next() is outstanding are queued, and return()/throw() before
the first next() complete the iterator without touching the stream.

The earlier delivery is observable by code racing an abort against
the first chunk. The flatMap AbortSignal test relied on such a race;
it is reworked to abort deterministically while two mappers are in
flight, asserting the concurrency limit, in-flight cancellation and
rejection, without depending on delivery timing or timers.

streams/readable-async-iterator.js sync='yes': +32.59% (***)
streams/readable-async-iterator.js sync='no': +9.84% (***)

Assisted-by: Claude Fable 5
Signed-off-by: Matteo Collina <[email protected]>
PR-URL: nodejs#64447
Reviewed-By: Gürgün Dayıoğlu <[email protected]>
Reviewed-By: Mattias Buelens <[email protected]>
Reviewed-By: Robert Nagy <[email protected]>
The highWaterMark values were passed as properties of the underlying
source and sink dictionaries, where they are ignored: a queuing
strategy's highWaterMark is read from the constructors' second argument.
Every configuration therefore measured the identical workload at the
default highWaterMark of 1, which also explains the historically high
run-to-run variance of this benchmark family.

Pass the strategies as the constructors' second argument and cover the
default (1) alongside buffered (1024, 4096) configurations.

Signed-off-by: Matteo Collina <[email protected]>
PR-URL: nodejs#65138
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Gürgün Dayıoğlu <[email protected]>
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Three related reductions on the per-chunk paths:

Wrap user sink.write and source.pull callbacks without coercing their
result into a promise. When the callback returns a non-thenable (the
common synchronous case), fulfillment is guaranteed and no then() lookup
is observable, so the fulfilled reaction is enqueued through a single
shared resolved promise at the exact microtask position the coerced
promise's reaction would have had, skipping the implicit async-wrapper
promise per chunk. Thenable results go through PromiseResolve(), which
matches the spec's "a promise resolved with" conversion (identity for
native promises).

Park pipeTo's pump on backpressure by installing a record that
duck-types the writer's lazily-materialized [[readyPromise]] record and
whose resolve function is the pump continuation itself. Backpressure
clearing then resumes the pump directly instead of materializing a fresh
promise record plus reaction per flip, and the pump no longer schedules
a microtask per batch. writableStreamUpdateBackpressure publishes the
new backpressure state before resolving the ready record so the pump
observes the updated value.

Replace queueMicrotask() on the pipeTo and tee chunk-forwarding paths
with a reaction on the shared resolved promise, which enqueues the
continuation at the same position without the per-call scheduling
overhead.

pipe-to improves by 8-14% across all benchmark configurations, with
readable-read and tee also improving in spot runs.

Signed-off-by: Matteo Collina <[email protected]>
PR-URL: nodejs#65138
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Gürgün Dayıoğlu <[email protected]>
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
The start, pull, and write non-op algorithms are all raw callbacks with
an identical empty body now, so a single shared nonOpCallback replaces
nonOpStart, nonOpPull, and nonOpWrite.

Signed-off-by: Matteo Collina <[email protected]>
PR-URL: nodejs#65138
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Gürgün Dayıoğlu <[email protected]>
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
The pointer range test creates multiple closures from the same function
literals and explicitly requests synchronous optimization. V8 can also
schedule concurrent recompilation for those closures.

Wait for background optimization before closing the dynamic library so
compiler jobs cannot outlive the fast FFI metadata they reference.

Signed-off-by: Kamat, Trivikram <[email protected]>
Assisted-by: codex:gpt-5.6-sol
PR-URL: nodejs#65300
Refs: https://github.com/nodejs/reliability/issues?q=sort%3Aupdated-desc%20%22test-ffi-fast-integer-validation%22
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Gürgün Dayıoğlu <[email protected]>
The quic implementation calls setWakeUp with
the assumption, that it is only executed once
per event loop cycle.
This assumption is wrong.
Only setImmediate will guarantee, that the
execution is delayed to later in the event loop
and happening once in the event loop.

Fixes: nodejs#64035
Signed-off-by: Marten Richter <[email protected]>
PR-URL: nodejs#64044
Reviewed-By: James M Snell <[email protected]>
Signed-off-by: Felix P. <[email protected]>
PR-URL: nodejs#65268
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Ethan Arrowood <[email protected]>
Signed-off-by: Guilherme Araújo <[email protected]>
PR-URL: nodejs#62241
Reviewed-By: Stephen Belanger <[email protected]>
Reviewed-By: René <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Signed-off-by: Filip Skokan <[email protected]>
Co-authored-by: Aviv Keller <[email protected]>
Signed-off-by: Aviv Keller <[email protected]>
PR-URL: nodejs#64894
Fixes: nodejs#43583
Reviewed-By: Filip Skokan <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matthew Aitken <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
To hopefully get to the bottom of WPT crashes that have no traces.

Signed-off-by: Filip Skokan <[email protected]>
Co-authored-by: Aviv Keller <[email protected]>
Signed-off-by: Aviv Keller <[email protected]>
PR-URL: nodejs#64894
Fixes: nodejs#43583
Reviewed-By: Filip Skokan <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matthew Aitken <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
Signed-off-by: Aviv Keller <[email protected]>
PR-URL: nodejs#64894
Fixes: nodejs#43583
Reviewed-By: Filip Skokan <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matthew Aitken <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
Signed-off-by: Filip Skokan <[email protected]>
Co-authored-by: Aviv Keller <[email protected]>
Signed-off-by: Aviv Keller <[email protected]>
PR-URL: nodejs#64894
Fixes: nodejs#43583
Reviewed-By: Filip Skokan <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matthew Aitken <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
Signed-off-by: Aviv Keller <[email protected]>
PR-URL: nodejs#64894
Fixes: nodejs#43583
Reviewed-By: Filip Skokan <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matthew Aitken <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
Signed-off-by: NIxxy25 <[email protected]>
PR-URL: nodejs#65271
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Aviv Keller <[email protected]>
Signed-off-by: Aviv Keller <[email protected]>
PR-URL: nodejs#64986
Reviewed-By: Antoine du Hamel <[email protected]>
Replace `Array.prototype.forEach()` with `for...of` loops across 17
tests in `test/parallel`, so each loop body reads as a plain statement
rather than an arrow callback.

None of the iterated values are sparse arrays, the one case where
`forEach` and `for...of` genuinely differ, so both constructs visit the
same elements in the same order. No callback relied on `this`, an early
return, or async behaviour, and the number of assertions run in each
file is unchanged.

Signed-off-by: Phillip Markert <[email protected]>
PR-URL: nodejs#65272
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Ethan Arrowood <[email protected]>
Signed-off-by: freida-code <[email protected]>
PR-URL: nodejs#65270
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Ethan Arrowood <[email protected]>
PR-URL: nodejs#65224
Reviewed-By: Filip Skokan <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Signed-off-by: Lazizbek Ergashev <[email protected]>
PR-URL: nodejs#65283
Fixes: nodejs#65280
Refs: nodejs/node-v0.x-archive#853
Refs: nodejs@3935adc
Refs: nodejs#18297
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: James M Snell <[email protected]>
the binary-upload target uses $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz as the
name to upload whereas it is created by the $(BINARYTAR) target as
$(BINARYNAME). Since BINARYNAME includes the optional VARIATION when
present this gets missed out int he binary-upload target, for example
during a release build for Alpine/musl. This commit changes the
binary-upload target to use the same variable for the tarball that is
used when the file is created.

Signed-off-by: Stewart X Addison <[email protected]>
PR-URL: nodejs#65282
Reviewed-By: Richard Lau <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Gürgün Dayıoğlu <[email protected]>
Signed-off-by: 서울민트초코 <[email protected]>
PR-URL: nodejs#65295
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Signed-off-by: greenhead <[email protected]>
PR-URL: nodejs#65274
Refs: nodejs#55266
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Daeyeon Jeong <[email protected]>
The error thrown for a non-number min is unchanged.

Signed-off-by: greenhead <[email protected]>
PR-URL: nodejs#65014
Reviewed-By: Daeyeon Jeong <[email protected]>
greenheadHQ and others added 29 commits August 17, 2026 03:39
The kValidateObjectAllowArray flag matches the replaced check: arrays
keep passing and the thrown error is unchanged.

Signed-off-by: greenhead <[email protected]>
PR-URL: nodejs#65015
Reviewed-By: James M Snell <[email protected]>
Use the standard SQLite integer conversion for changes and
lastInsertRowid. Throw ERR_OUT_OF_RANGE when a value cannot be
represented safely as a Number, or return it as a BigInt when
BigInt reads are enabled.

Signed-off-by: Kamat, Trivikram <[email protected]>
Assisted-by: codex:gpt-5.6-sol
PR-URL: nodejs#65178
Fixes: nodejs#65177
Reviewed-By: Stephen Belanger <[email protected]>
Validate Broadcast.push() and Share.pull() signals before registering
raw consumers. Return a rejecting iterable for pre-aborted signals
without adding a cursor.

This prevents failed subscriptions from leaving unreachable cursors
that inflate consumerCount and can permanently impose backpressure.

Signed-off-by: Kamat, Trivikram <[email protected]>
Assisted-by: codex:gpt-5.6-sol
PR-URL: nodejs#65299
Fixes: nodejs#65298
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jason Zhang <[email protected]>
Add a WatchdogBinding declaration for internalBinding('watchdog')
and wire it into InternalBindingMap.

Signed-off-by: leah-1ee <[email protected]>
PR-URL: nodejs#65228
Reviewed-By: Daeyeon Jeong <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Add a DiagnosticsChannelBinding declaration for
internalBinding('diagnostics_channel') and wire it into
InternalBindingMap.

Signed-off-by: leah-1ee <[email protected]>
PR-URL: nodejs#65227
Reviewed-By: Daeyeon Jeong <[email protected]>
Reviewed-By: James M Snell <[email protected]>
The inspector can accept a connection before an --inspect-brk target
enters its frontend wait. Runtime.runIfWaitingForDebugger can then be
handled too early, allowing the target to subsequently block forever.

Wait for NodeRuntime.waitingForDebugger before initializing and
releasing launched targets. Race the handshake against disconnects and
apply it to both interactive and probe startup.

Refs: nodejs#64116
Assisted-by: codex:gpt-5.6-sol
Co-authored-by: Archkon <[email protected]>
Signed-off-by: Archkon <[email protected]>
Signed-off-by: Filip Skokan <[email protected]>
PR-URL: nodejs#65194
Reviewed-By: Trivikram Kamat <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Add a SignalWrapBinding declaration for internalBinding('signal_wrap')
and wire it into InternalBindingMap.

Signed-off-by: leah-1ee <[email protected]>
PR-URL: nodejs#65229
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daeyeon Jeong <[email protected]>
PR-URL: nodejs#61198
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Jordan Harband <[email protected]>
Signed-off-by: Antoine du Hamel <[email protected]>
PR-URL: nodejs#65198
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Use concise method functions for Fast API and shared-buffer wrappers,
and create native fallback functions with ConstructorBehavior::kThrow,
so FFI functions remain non-constructible on all invocation paths.

Signed-off-by: Kamat, Trivikram <[email protected]>
Assisted-by: codex:gpt-5.6-sol
PR-URL: nodejs#65184
Fixes: nodejs#65183
Reviewed-By: Paolo Insogna <[email protected]>
InvokeCallback tested `args[i] == nullptr` and mapped the argument to
JS `null`. `args` is libffi's avalue array, and libffi always points
each slot at its own storage for the corresponding argument, so the
slot pointers are never null and the branch never ran.

The check also read as a guarantee the code does not provide: a NULL
pointer argument surfaces as the BigInt `0n`, because ToJSArgument
converts `ffi_type_pointer` values with BigInt::NewFromUnsigned. Drop
the branch rather than reimplementing it in ToJSArgument, which would
change behavior by making pointer parameters arrive as either a BigInt
or `null`.

Signed-off-by: Trivikram Kamat <[email protected]>
Assisted-by: claude:opus-5
PR-URL: nodejs#64998
Reviewed-By: Paolo Insogna <[email protected]>
Signed-off-by: avivkeller <[email protected]>
PR-URL: nodejs#64590
Reviewed-By: James M Snell <[email protected]>
Long-term itch. Per v8 rules, we're not supposed to be
heap allocating v8::Local's; instead we're supposed to
be using v8::LocalVector. Create a specialization of
MaybeStackBuffer that uses either a stack array of
v8::Locals or v8::LocalVector with some additional
utility improvements.

Signed-off-by: James M Snell <[email protected]>
PR-URL: nodejs#65159
Reviewed-By: Stephen Belanger <[email protected]>
`maybeEnableKeylog()` runs as the agent's `'newListener'` handler and
attaches the agent's keylog handler to the sockets the agent already
owns. `agent.sockets` maps a name to an array of sockets, but the loop
treated those arrays as sockets and called `.on()` on them.

Adding a `'keylog'` listener to an agent that already owned a socket
therefore threw `TypeError: sockets[i].on is not a function` out of
`agent.on('keylog', ...)`. Since the throw happened inside the
`'newListener'` handler it propagated before the listener was stored,
so the caller got an exception and no listener. Sockets parked in
`agent.freeSockets` were never visited at all.

Walk both maps the way `Agent.prototype.destroy()` does.

Signed-off-by: Shani Singh <[email protected]>
PR-URL: nodejs#65066
Reviewed-By: Tim Perry <[email protected]>
Fixes: nodejs#64214
Signed-off-by: y1d7ng <[email protected]>
PR-URL: nodejs#64227
Reviewed-By: Chemi Atlow <[email protected]>
Reviewed-By: Claudio Wunder <[email protected]>
Signed-off-by: ulofiai <[email protected]>
PR-URL: nodejs#65095
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Stefan Stojanovic <[email protected]>
An expired timer can run before the first complete event loop
iteration, disabling the histogram before it records any samples.

Drive a known number of iterations with setImmediate before checking
the histograms, and share the chain between resolution variants.

Signed-off-by: Kamat, Trivikram <[email protected]>
Assisted-by: codex:gpt-5.6-sol
PR-URL: nodejs#64728
Refs: https://github.com/nodejs/reliability/issues?q=sort%3Aupdated-desc%20test-performance-eventloopdelay
Reviewed-By: Filip Skokan <[email protected]>
PR-URL: nodejs#65317
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Chemi Atlow <[email protected]>
Signed-off-by: Filip Skokan <[email protected]>
PR-URL: nodejs#65320
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Signed-off-by: geeksilva97 <[email protected]>
PR-URL: nodejs#65276
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Add return types for Blob methods and legacy Base64 helpers so doc-kit
does not render them as `void`.

Refs: nodejs/doc-kit#953
Signed-off-by: inoway46 <[email protected]>
PR-URL: nodejs#65308
Refs: nodejs/doc-kit#953
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Three entries in the fs documentation described their return
value only in prose, or not at all, so doc-kit could not parse
a return type and fell back to `void`:

* `filehandle[Symbol.asyncDispose]()` and
  `dir[Symbol.asyncDispose]()` both return a promise, matching
  the existing `Returns: {Promise}` annotations on other async
  dispose methods.
* `new fs.Utf8Stream([options])` is a constructor and returns
  an instance of the class.

Verified at runtime and by rendering the page locally with
doc-kit.

Refs: nodejs/doc-kit#953
Signed-off-by: Chxxeton <[email protected]>
PR-URL: nodejs#65307
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Ulises Gascón <[email protected]>
The prior text covered only two of the seven supported architectures
and conflated x86-64 SysV with the stricter Win64 emitter.

Signed-off-by: leah-1ee <[email protected]>
PR-URL: nodejs#65207
Reviewed-By: Paolo Insogna <[email protected]>
Fixes: nodejs#63852
Signed-off-by: Erik Demaine <[email protected]>
PR-URL: nodejs#63856
Reviewed-By: Stefan Stojanovic <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
Signed-off-by: T <[email protected]>
PR-URL: nodejs#62941
Fixes: nodejs#61518
Reviewed-By: Aviv Keller <[email protected]>
Bumps [undici](https://github.com/nodejs/undici) from 6.27.0 to 6.28.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](nodejs/undici@v6.27.0...v6.28.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 6.28.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
PR-URL: nodejs#65011
Reviewed-By: Colin Ihrig <[email protected]>
Signed-off-by: James Ross <[email protected]>
PR-URL: nodejs#64886
Reviewed-By: Aviv Keller <[email protected]>
Reviewed-By: Stefan Stojanovic <[email protected]>
Reviewed-By: Ulises Gascón <[email protected]>
Move path validation, file URL conversion, NUL checks, mode
validation, permission checks, and the copy into a dedicated
C++ binding so fs.copyFileSync() no longer goes through
getValidatedPath() in JavaScript.

VFS dispatch stays in JS and still runs before validation.
The copy itself uses uv_fs_copyfile, so flags, mode/timestamp
preservation, and UV error shapes stay the same.

Also fix FileURLToPath aborting on file URLs with a hostname
because the ERR_INVALID_FILE_URL_HOST format string lacked %s.

Signed-off-by: Yagiz Nizipli <[email protected]>
Fold getValidatedPath, file URL conversion, and NUL checks into
binding.copyFile so the sync, callback, and promises paths share
one implementation. Remove the extra copyFileSync binding.

Signed-off-by: Cursor Agent <[email protected]>

Co-authored-by: Yagiz Nizipli <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.