diff --git a/src/modules/url.c b/src/modules/url.c index b00f4c1..98678eb 100644 --- a/src/modules/url.c +++ b/src/modules/url.c @@ -47,7 +47,14 @@ static ant_value_t usp_array_len(ant_t *js, ant_value_t arr, ant_offset_t *out) ant_value_t length = js_get(js, arr, "length"); if (is_err(length)) return length; if (js->thrown_exists) return mkval(T_ERR, 0); - if (vtype(length) == T_NUM) *out = (ant_offset_t)tod(length); + + double len_num = js_to_number(js, length); + if (js->thrown_exists) return mkval(T_ERR, 0); + + if (isnan(len_num) || !isfinite(len_num)) + return js_mkerr_typed(js, JS_ERR_TYPE, "URLSearchParams sequence length must be finite"); + + *out = (ant_offset_t)js_to_uint32(len_num); return js_mkundef(); } diff --git a/tests/test_proxy_array_flat_urlsearchparams.cjs b/tests/test_proxy_array_flat_urlsearchparams.cjs index fe3f26e..dbd8d22 100644 --- a/tests/test_proxy_array_flat_urlsearchparams.cjs +++ b/tests/test_proxy_array_flat_urlsearchparams.cjs @@ -31,6 +31,14 @@ assert(params.toString() === "a=b", "URLSearchParams should accept proxied array assert(sawOuterLength, "URLSearchParams should observe outer proxy length"); assert(sawPairLength, "URLSearchParams should observe pair proxy length"); +const stringLengthParams = new URLSearchParams(new Proxy([pair], { + get(target, key, receiver) { + if (key === "length") return "1"; + return Reflect.get(target, key, receiver); + }, +})); +assert(stringLengthParams.toString() === "a=b", "URLSearchParams should convert proxy length with ToNumber"); + assertThrows( function () { new URLSearchParams(new Proxy([pair], { @@ -70,6 +78,32 @@ assertThrows( "URLSearchParams should propagate pair proxy value errors" ); +assertThrows( + function () { + new URLSearchParams(new Proxy([pair], { + get(target, key, receiver) { + if (key === "length") return NaN; + return Reflect.get(target, key, receiver); + }, + })); + }, + "finite", + "URLSearchParams should reject NaN proxy lengths" +); + +assertThrows( + function () { + new URLSearchParams(new Proxy([pair], { + get(target, key, receiver) { + if (key === "length") return { valueOf() { throw new Error("length convert boom"); } }; + return Reflect.get(target, key, receiver); + }, + })); + }, + "length convert boom", + "URLSearchParams should propagate proxy length conversion errors" +); + console.log("OK"); function assertThrows(fn, expected, message) {