jscript: Refill the props at end of enumeration in html mode and retry.

If properties were added during enumeration, for example on the prototype,
they are actually visited in mshtml scripts in any mode.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
Gabriel Ivăncescu 2022-10-10 19:55:22 +03:00 committed by Alexandre Julliard
parent 2a228918ef
commit 605819dcd9
3 changed files with 30 additions and 5 deletions

View file

@ -2492,16 +2492,16 @@ HRESULT jsdisp_next_prop(jsdisp_t *obj, DISPID id, enum jsdisp_enum_type enum_ty
DWORD idx = id;
HRESULT hres;
if(id == DISPID_STARTENUM) {
if(id == DISPID_STARTENUM || idx >= obj->prop_cnt) {
hres = (enum_type == JSDISP_ENUM_ALL) ? fill_protrefs(obj) : fill_props(obj);
if(FAILED(hres))
return hres;
idx = 0;
if(id == DISPID_STARTENUM)
idx = 0;
if(idx >= obj->prop_cnt)
return S_FALSE;
}
if(idx >= obj->prop_cnt)
return S_FALSE;
for(iter = &obj->props[idx]; iter < obj->props + obj->prop_cnt; iter++) {
if(iter->type == PROP_DELETED)
continue;
@ -2513,6 +2513,9 @@ HRESULT jsdisp_next_prop(jsdisp_t *obj, DISPID id, enum jsdisp_enum_type enum_ty
return S_OK;
}
if(obj->ctx->html_mode)
return jsdisp_next_prop(obj, prop_to_id(obj, iter - 1), enum_type, ret);
return S_FALSE;
}

View file

@ -1559,6 +1559,7 @@ inobj.test2 = true;
tmp = 0;
for(iter in inobj) {
forinTestObj.prototype.test4 = true;
arr[iter] = true;
tmp++;
}
@ -1567,6 +1568,7 @@ ok(tmp === 3, "for..in tmp = " + tmp);
ok(arr["test1"] === true, "arr[test1] !== true");
ok(arr["test2"] === true, "arr[test2] !== true");
ok(arr["test3"] === true, "arr[test3] !== true");
ok(arr["test4"] !== true, "arr[test4] === true");
ok((delete inobj.test1) === true, "delete inobj.test1 returned false");
ok(!("test1" in inobj), "test1 is still in inobj after delete");

View file

@ -634,6 +634,26 @@ sync_test("JS objs", function() {
test_parses("if(false) { o.if; }", v >= 9);
});
sync_test("for..in", function() {
function ctor() {}
ctor.prototype.test2 = true;
var arr = new Array(), obj = new ctor(), i, r;
obj.test1 = true;
i = 0;
for(var r in obj) {
ctor.prototype.test3 = true;
arr[r] = true;
i++;
}
ok(i === 3, "enum did " + i + " iterations");
ok(arr["test1"] === true, "arr[test1] !== true");
ok(arr["test2"] === true, "arr[test2] !== true");
ok(arr["test3"] === true, "arr[test3] !== true");
});
sync_test("elem_by_id", function() {
document.body.innerHTML = '<form id="testid" name="testname"></form>';