Skip to content

Use ToLength for the argument list length in apply - #1816

Open
fhgffy wants to merge 1 commit into
quickjs-ng:masterfrom
fhgffy:fix/apply-negative-length
Open

fhgffy wants to merge 1 commit into
quickjs-ng:masterfrom
fhgffy:fix/apply-negative-length

Conversation

@fhgffy

@fhgffy fhgffy commented Oct 9, 2026

Copy link
Copy Markdown

build_arg_list() read the length of the array-like with ToUint32, so f.apply(null, { length: -1 }) threw "RangeError: too many arguments in function call" and a length like 2 ** 32 + 1 wrapped around to 1. CreateListFromArrayLike goes through LengthOfArrayLike (ToLength), which clamps negative values to 0. The same helper backs Reflect.apply and Reflect.construct, so those are fixed too.

The length is now read with js_get_length64() and checked against the argument limit before narrowing. With the patch:

function f() { return arguments.length }
f.apply(null, { length: -1 })          // 0
Reflect.apply(f, null, { length: -1 }) // 0
f.apply(null, { length: 2 ** 32 + 1 }) // RangeError instead of calling f with one argument

Added cases to test_function in tests/test_builtin.js (they fail without the change). make test passes and make test262 shows no change against test262_errors.txt.

Fixes #1764

Function.prototype.apply, Reflect.apply and Reflect.construct read the
length of the argument list with ToUint32, so a negative length turned
into 2^32 - 1 and threw a RangeError, and a length above 2^32 wrapped
around. CreateListFromArrayLike uses LengthOfArrayLike, which clamps
negative values to 0.

Fixes: quickjs-ng#1764

@bnoordhuis bnoordhuis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and good catch but this suggests to me that we should either:

  • change js_get_length32 so it clamps values instead of wrapping, or
  • excise it from the code base altogether

This branch has not been deployed

No deployments
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.

Function.prototype.apply throws RangeError for a negative length

2 participants