[PATCH v2 8/8] jscript: Make idx props enumerable.

Gabriel Ivăncescu gabrielopcode at gmail.com
Thu Mar 24 10:31:13 CDT 2022


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/jscript/dispex.c    | 17 ++++++++++++++++-
 dlls/mshtml/tests/es5.js | 28 +++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 32265d3..6ee02a0 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -285,7 +285,10 @@ static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name,
         for(ptr = name; is_digit(*ptr) && idx < 0x10000; ptr++)
             idx = idx*10 + (*ptr-'0');
         if(!*ptr && idx < This->builtin_info->idx_length(This)) {
-            prop = alloc_prop(This, name, PROP_IDX, This->builtin_info->idx_put ? PROPF_WRITABLE : 0);
+            unsigned flags = PROPF_ENUMERABLE;
+            if(This->builtin_info->idx_put)
+                flags |= PROPF_WRITABLE;
+            prop = alloc_prop(This, name, PROP_IDX, flags);
             if(!prop)
                 return E_OUTOFMEMORY;
 
@@ -2444,6 +2447,18 @@ HRESULT jsdisp_next_prop(jsdisp_t *obj, DISPID id, enum jsdisp_enum_type enum_ty
     HRESULT hres;
 
     if(id == DISPID_STARTENUM) {
+        if(obj->builtin_info->idx_length) {
+            unsigned i = 0, len = obj->builtin_info->idx_length(obj);
+            WCHAR name[12];
+
+            for(i = 0; i < len; i++) {
+                swprintf(name, ARRAY_SIZE(name), L"%d", i);
+                hres = find_prop_name(obj, string_hash(name), name, &iter);
+                if(FAILED(hres))
+                    return hres;
+            }
+        }
+
         if (enum_type == JSDISP_ENUM_ALL) {
             hres = fill_protrefs(obj);
             if(FAILED(hres))
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index 0339d9b..2f78ca8 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -654,12 +654,38 @@ sync_test("property_definitions", function() {
 });
 
 sync_test("string_idx", function() {
-    var s = "foobar";
+    var i, s = "foobar";
     ok(s[0] === "f", "s[0] = " + s[0]);
     ok(s[5] === "r", "s[5] = " + s[5]);
     ok(s[6] === undefined, "s[6] = " + s[6]);
     ok((delete s[0]) === false, "delete s[0] returned true");
     ok((delete s[6]) === true, "delete s[6] returned false");
+    s[6] = "X";
+    ok(s[6] === undefined, "s[6] = " + s[6]);
+
+    s = new String(s);
+    test_own_data_prop_desc(s, "0", false, true, false);
+    test_own_data_prop_desc(s, "1", false, true, false);
+    ok(!Object.prototype.hasOwnProperty.call(s, "6"), "'6' is a property");
+
+    s[7] = "X";
+    ok(s[7] === "X", "s[7] = " + s[7]);
+    ok(Object.prototype.hasOwnProperty.call(s, "7"), "'7' not a property");
+
+    Object.defineProperty(s, "8", {writable: false, enumerable: true, configurable: true, value: "Y"});
+    ok(s[8] === "Y", "s[8] = " + s[8]);
+    ok(Object.prototype.hasOwnProperty.call(s, "8"), "'8' not a property");
+
+    String.prototype[9] = "Z";
+    ok(s[9] === "Z", "s[9] = " + s[9]);
+    delete String.prototype[9];
+
+    i = 0;
+    for(var idx in s) {
+        ok(s[idx] === "foobar XY"[idx], "enum s[" + idx + "] = " + s[idx]);
+        i++;
+    }
+    ok(i === 8, "enum did " + i + " iterations");
 });
 
 sync_test("string_trim", function() {
-- 
2.34.1




More information about the wine-devel mailing list