fs.cpSync, fs.cp and fs/promises cp compile with every option:
dereference, errorOnExist, filter, force, mode, preserveTimestamps,
recursive and verbatimSymlinks. They follow Node's two implementations.
cpSync follows cp-sync.js over the fs binding: copy errors are plain
Errors with a code, std::error_code failures throw an ErrnoException,
and links inside a copied directory point at their canonical targets.
fs.cp and fs/promises cp follow cp.js, whose copy errors are
SystemErrors with code, info, errno, syscall and path.
Options and paths validate in Node's order with Node's errors. filter
runs for the top-level paths and each entry in Node's order; an async
filter must return a promise that is already settled, and a pending one
throws SC2020. The callback and promise forms complete the copy before
the callback runs or the promise settles. Windows builds throw SC2020.
The copy lives in the new scr_fs_cp.c. Directory walks keep their frames
on the heap, so deep trees also copy on a fiber's stack. File contents
copy with sendfile on Linux, and COPYFILE_FICLONE uses FICLONE
where it exists. ScrError gains the SystemError context and the
ErrnoException key order, with matching fields in the compiler's Error
layout. The stored fs.cp callback uses the same implementation.
Corpus 5567-5571 cover the sync, callback and promise forms, errors,
symlinks and 1500-level trees.
createCipheriv, createDecipheriv, update(), setAAD() and setAuthTag()
now read the value a typed-ref box holds when it is a string, view,
ArrayBuffer or KeyObject. ERR_INVALID_ARG_TYPE names the class of a
class instance that arrives through an untyped value, as Node does,
instead of Object. An unknown output encoding that is not a string is
rendered as Node's %s formats it (util.inspect at depth 0, or the
object's own toString); a function, or an instance of a class that
defines toString, throws a coded SC2020 error. Cipher programs link the
inspect unit for that rendering.
5250 passes each argument through `any`, including class instances,
records and arrays that Node rejects, and 5254 covers output encodings
that are not strings from JavaScript.
- Every mbedTLS call in the cipher runtime is checked. A failed update(),
final() or setAAD() returns no output and retires the context, so later
calls throw and no tag is returned or accepted. An update past the
AES-GCM limit of 2^36 - 32 bytes per message throws Node's "Trying to
add data in unsupported state" error; it used to return zeroed output
and leave the tag covering only the earlier data.
- chacha20-poly1305 decryption without setAuthTag() fails in final()
again. Node 24.22 skips the tag check when authTagLength is not passed
either and returns unverified plaintext; limitations.mdx records the
difference.
- A runtime unit test moves contexts next to the GCM message and AAD
limits and checks that the failure is permanent; errors.test.ts covers
decryption without a tag.