Array iterator, Proxy ownKeys and RegExp @@replace read `length` with ToUint32 instead of ToLength

Đang mở
#1,890 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
57/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
c, javascript
Lĩnh vực
backend, operating-systems

Hướng nghiên cứu

Start by reading js_array_iterator_next, js_proxy_get_own_property_names, js_regexp_Symbol_replace, and js_string_GetSubstitution, which the issue identifies as using js_get_length32(). Compare with the js_get_length64() change in #1816 and the relevant ECMAScript length rules. Done means the reported negative and above-2^32 cases follow ToLength semantics, with limits handled without wrapping; run the reproductions and the related tests.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Environment
  • QuickJS-ng v0.18.0 (d7215b0) and master e22ce4d (2026-11-02), built with make, Debian 12 x86-64, gcc 12.2
  • Also seen in v0.15.0
  • Reference: node v26.13.0
  • Checked on 2026-11-03
Reproduction
// 1. array iterator, negative length (terminates)
var n = 0;
for (var x of Array.prototype.values.call({ length: -1, 0: "a" })) { if (++n > 3) break; }
console.log(n);                       // expected 0, actual 4

// 2. array iterator, length above 2**32 wraps
n = 0;
for (var k of Array.prototype.keys.call({ length: 2 ** 32 + 1 })) { if (++n > 5) break; }
console.log(n);                       // expected 6, actual 1

// 3. Proxy ownKeys trap result with a negative length
console.log(Reflect.ownKeys(new Proxy({}, { ownKeys() { return { length: -1, 0: "a" }; } })).length);
                                      // expected 0, actual TypeError

// 4. Proxy ownKeys trap result with length 2**32 + 1
console.log(Reflect.ownKeys(new Proxy({}, { ownKeys() { return { length: 2 ** 32 + 1, 0: "a" }; } })).length);
                                      // expected TypeError (index 1 is undefined) or a RangeError limit, actual 1

These do not terminate (about 2^32 iterations), run with a timeout:

console.log([...Array.prototype.values.call({ length: -1, 0: "a" })].length);   // expected 0

var re = /x/;
re.exec = function () { re.exec = () => null; return { length: -1, 0: "x", index: 0 }; };
console.log("x".replace(re, "[$&]"));                                           // expected [x]
Expected (spec)

All of these read the length with LengthOfArrayLike, that is
ToLength(Get(obj, "length")), which clamps to [0, 2^53 − 1]: ToLength(−1) is 0, and 2^32 + 1 stays 2^32 + 1.

ToUint32 maps −1 to 2^32 − 1 and 2^32 + 1 to 1, which explains every result above.

Cause

These sites use js_get_length32() (ToUint32):

  • js_array_iterator_next
  • js_proxy_get_own_property_names
  • js_regexp_Symbol_replace (nCaptures) and js_string_GetSubstitution (captures)

A possible fix (not written or tested): read the length with js_get_length64() (ToLength), as #1816 does for
build_arg_list. Above what a site can represent, throw a RangeError instead of wrapping (ownKeys, captures), or use a
64-bit index (the array iterator).

Related
  • #1764 / #1816: the same conversion in build_arg_list (Function.prototype.apply, Reflect.apply, Reflect.construct). That PR does not touch the sites above.
  • #1609: fixed an allocation overflow in the Proxy ownKeys path. The length conversion there is still ToUint32.
  • bellard/quickjs has the same code at these sites (its apply already uses ToLength).
Ngôn ngữ chính
C
Star
3.9k
Fork
389
Merge trung bình
4 ngày 5 giờ
Pull request đã merge (30 ngày)
16

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của quickjs-ng/quickjs

Tất cả issue của quickjs-ng/quickjs

Issue tương tự

Thêm issue về C

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.