Repository navigation
fix(node): throw spec arg-validation errors for fs/process/zlib (#3662) - #4082
Merged
Merged
Conversation
Node-core argument-validation sub-cluster of #3662: make `zlib`, `process`, and `fs` builtins throw the spec-mandated `TypeError [ERR_INVALID_ARG_TYPE]` / `RangeError [ERR_OUT_OF_RANGE]` on invalid arguments instead of silently proceeding. (The `Function.prototype` not-callable checks landed in #4073 and the collection brand checks in #3739; this change is the node-core piece.) zlib option validation — new shared `js_zlib_validate_options(opts, min_wb)` in perry-runtime, called by the in-tree (perry-stdlib) *and* out-of-tree (perry-ext-zlib, used by the auto-optimize build) codecs from `gzipSync` / `deflateSync` and every `create*` stream factory. Validates `windowBits`, `level`, `memLevel`, `strategy`, `chunkSize`, and `flush` in Node's exact field order so the first-offender message matches; `windowBits` lower bound is 9 for gzip compression and 8 elsewhere. A non-numeric option throws the `"options.<name>" property must be of type number` TypeError; an out-of-range one throws the matching RangeError. zlib buffer-arg validation — new `js_zlib_validate_buffer_arg` rejects a non-string/Buffer/TypedArray/DataView/ArrayBuffer first argument to the gzip/gunzip/deflate/inflate sync codecs in the ext path (stdlib already did so inline). brotli's ext (pointer-based) codec is left as a follow-up. process.emitWarning — validates the `warning` argument (string or Error) and the `type` positional (string), matching Node's ordering. fs.mkdirSync — validates the options object's `recursive` (boolean) and `mode` (number/string) properties. New gap test test_gap_3662_node_argvalidation.ts is byte-for-byte identical to `node --experimental-strip-types` in both the default auto-optimize and `PERRY_NO_AUTO_OPTIMIZE=1` builds.
proggeramlug
added a commit
that referenced
this pull request
Jun 2, 2026
Typed-array constructors silently clamped a negative or out-of-range length argument to 0 instead of throwing the spec-mandated RangeError. This is the ECMAScript-constructor slice of the #3662 "builtins must throw" cluster (collection brand checks landed in #3739, Function.proto in #4073, node-core fs/zlib/process in #4082). Add a shared ToIndex-style length validator: truncate toward zero (NaN -> 0, 2.5 -> 2, no throw) and throw a plain `RangeError: Invalid typed array length: <n>` (no .code, matching Node) when the resulting integer is negative, Infinity, or >= 2**53. - typedarray.rs: typed_array_length_or_throw, wired into js_typed_array_new_empty (literal-length path) and js_typed_array_new (INT32-tagged and plain-double runtime-dispatch paths) for Int8/16/32, Uint16/32, Float32/64, Uint8ClampedArray. - buffer/from.rs: uint8array_length_or_throw, wired into js_uint8array_alloc (literal path) and js_uint8array_new (runtime path) — Uint8Array is backed by a BufferHeader in Perry. - codegen arrays_finds.rs: stop clamping the literal integer length with .max(0) so a negative literal reaches the runtime validator. New gap test test_gap_3662_typedarray_length.ts is byte-identical to node --experimental-strip-types in both the default auto-optimize and PERRY_NO_AUTO_OPTIMIZE=1 builds. Co-authored-by: Ralph Küpper <ralph@skelpo.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Node-core argument-validation sub-cluster of #3662: make
zlib,process, andfsbuiltins throw the spec-mandatedTypeError [ERR_INVALID_ARG_TYPE]/RangeError [ERR_OUT_OF_RANGE]on invalid arguments instead of silently proceeding.Scope boundary: the
Function.prototypenot-callable checks landed in #4073 and the collection (Set/Map/Weak*) brand checks in #3739 — this PR is the remaining node-core piece (fs / process / zlib).What changed
zlib option validation — new shared
js_zlib_validate_options(opts, min_window_bits)inperry-runtime, called from both the in-tree (perry-stdlib) and out-of-tree (perry-ext-zlib, used by the auto-optimize build) codecs: fromgzipSync/deflateSyncand everycreate*stream factory. ValidateswindowBits,level,memLevel,strategy,chunkSize, andflushin Node's exact field order so the first-offender message matches Node when several options are bad.windowBitslower bound is 9 for gzip compression and 8 for every other codec (mirrors Node'sZ_MIN_WINDOWBITS). A non-numeric option throws the"options.<name>" property must be of type numberTypeError; an out-of-range one throws the matchingERR_OUT_OF_RANGERangeError.zlib buffer-arg validation — new
js_zlib_validate_buffer_argrejects a non-string/Buffer/TypedArray/DataView/ArrayBuffer first argument to thegzip/gunzip/deflate/inflatesync codecs in the ext path (the stdlib path already validated this inline viacodec_bytes). brotli's ext codec takes a pre-unboxed pointer (calling-convention quirk) and is left as a follow-up — the stdlib path already validates it.process.emitWarning — validates the
warningargument (must be a string orError) and thetypepositional (must be a string), in Node's order (type before warning).fs.mkdirSync — validates the options object's
recursive(boolean) andmode(number/string) properties.Testing
New gap test
test-files/test_gap_3662_node_argvalidation.tsis byte-for-byte identical tonode --experimental-strip-typesin both the default auto-optimize build andPERRY_NO_AUTO_OPTIMIZE=1:cargo test --release -p perry-runtime→ 964 passed, 0 failedcargo fmt --all -- --check→ cleancreateGzip, recursivemkdirSync, stringemitWarning) stay working.Follow-ups (not in scope here)
writeFileSyncbad-encodingERR_INVALID_ARG_VALUE,readSyncbuffer-before-fd order) — separate, riskier touches to hot paths.Closes part of #3662.