Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/object.c | 44 ++++++++++++++++ dlls/mshtml/tests/documentmode.js | 88 +++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+)
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index 9d4a747..d7650ff 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -294,6 +294,49 @@ done: return hres; }
+static HRESULT Object_defineGetter(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + property_desc_t desc; + const WCHAR *name; + jsstr_t *name_str; + jsdisp_t *jsthis; + HRESULT hres; + + TRACE("\n"); + + if(!is_object_instance(vthis) || !(jsthis = to_jsdisp(get_object(vthis)))) + goto done; + + if(argc < 2 || !is_object_instance(argv[1])) + return JS_E_FUNCTION_EXPECTED; + + desc.getter = to_jsdisp(get_object(argv[1])); + if(!desc.getter) { + FIXME("getter is not JS object\n"); + return E_NOTIMPL; + } + /* FIXME: Check IsCallable */ + + hres = to_flat_string(ctx, argv[0], &name_str, &name); + if(FAILED(hres)) + return hres; + + desc.flags = desc.mask = PROPF_CONFIGURABLE | PROPF_ENUMERABLE; + desc.explicit_getter = TRUE; + desc.explicit_setter = FALSE; + desc.explicit_value = FALSE; + desc.setter = NULL; + hres = jsdisp_define_property(jsthis, name, &desc); + + jsstr_release(name_str); + if(FAILED(hres)) + return hres; +done: + if(r) + *r = jsval_undefined(); + return S_OK; +} + HRESULT Object_get_proto_(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis; @@ -365,6 +408,7 @@ static void Object_destructor(jsdisp_t *dispex) }
static const builtin_prop_t Object_props[] = { + {L"__defineGetter__", Object_defineGetter, PROPF_METHOD|PROPF_ES6|2}, {L"hasOwnProperty", Object_hasOwnProperty, PROPF_METHOD|1}, {L"isPrototypeOf", Object_isPrototypeOf, PROPF_METHOD|1}, {L"propertyIsEnumerable", Object_propertyIsEnumerable, PROPF_METHOD|1}, diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 2902902..18dd65e 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1415,6 +1415,94 @@ sync_test("__proto__", function() { } });
+sync_test("__defineGetter__", function() { + var v = document.documentMode; + var r, x = 42; + + if(v < 11) { + ok(x.__defineGetter__ === undefined, "x.__defineGetter__ = " + x.__defineGetter__); + ok(!("__defineGetter__" in Object), "Object.__defineGetter__ = " + Object.__defineGetter__); + return; + } + ok(Object.prototype.hasOwnProperty("__defineGetter__"), "__defineGetter__ is not a property of Object.prototype"); + ok(Object.prototype.__defineGetter__.length === 2, "__defineGetter__.length = " + Object.prototype.__defineGetter__.length); + + function getter() { return "wine"; } + function setter(val) { } + + r = x.__defineGetter__("foo", getter); + ok(r === undefined, "__defineGetter__ on 42 returned " + r); + ok(x.foo === undefined, "42.foo = " + x.foo); + + x = {}; + r = x.__defineGetter__("foo", getter); + ok(r === undefined, "__defineGetter__ returned " + r); + ok(x.foo === "wine", "x.foo = " + x.foo); + r = Object.getOwnPropertyDescriptor(x, "foo"); + ok(r.value === undefined, "x.foo value = " + r.value); + ok(r.get === getter, "x.foo get = " + r.get); + ok(r.set === undefined, "x.foo set = " + r.set); + ok(r.writable === undefined, "x.foo writable = " + r.writable); + ok(r.enumerable === true, "x.foo enumerable = " + r.enumerable); + ok(r.configurable === true, "x.foo configurable = " + r.configurable); + + Object.defineProperty(x, "foo", { get: undefined, set: setter, configurable: false }); + r = Object.getOwnPropertyDescriptor(x, "foo"); + ok(r.value === undefined, "x.foo setter value = " + r.value); + ok(r.get === undefined, "x.foo setter get = " + r.get); + ok(r.set === setter, "x.foo setter set = " + r.set); + ok(r.writable === undefined, "x.foo setter writable = " + r.writable); + ok(r.enumerable === true, "x.foo setter enumerable = " + r.enumerable); + ok(r.configurable === false, "x.foo setter configurable = " + r.configurable); + try { + x.__defineGetter__("foo", getter); + ok(false, "expected exception calling __defineGetter__ on non-configurable property"); + }catch(e) { + ok(e.number === 0xa13d6 - 0x80000000, "__defineGetter__ on non-configurable property threw exception " + e.number); + } + + r = Object.prototype.__defineGetter__.call(undefined, "bar", getter); + ok(r === undefined, "__defineGetter__ on undefined returned " + r); + r = Object.prototype.__defineGetter__.call(null, "bar", getter); + ok(r === undefined, "__defineGetter__ on null returned " + r); + r = x.__defineGetter__(undefined, getter); + ok(r === undefined, "__defineGetter__ undefined prop returned " + r); + ok(x["undefined"] === "wine", "x.undefined = " + x["undefined"]); + r = x.__defineGetter__(false, getter); + ok(r === undefined, "__defineGetter__ undefined prop returned " + r); + ok(x["false"] === "wine", "x.false = " + x["false"]); + + try { + x.__defineGetter__("bar", "string"); + ok(false, "expected exception calling __defineGetter__ with string"); + }catch(e) { + ok(e.number === 0xa138a - 0x80000000, "__defineGetter__ with string threw exception " + e.number); + } + try { + x.__defineGetter__("bar", undefined); + ok(false, "expected exception calling __defineGetter__ with undefined"); + }catch(e) { + ok(e.number === 0xa138a - 0x80000000, "__defineGetter__ with undefined threw exception " + e.number); + } + try { + x.__defineGetter__("bar", null); + ok(false, "expected exception calling __defineGetter__ with null"); + }catch(e) { + ok(e.number === 0xa138a - 0x80000000, "__defineGetter__ with null threw exception " + e.number); + } + try { + Object.prototype.__defineGetter__.call(x, "bar"); + ok(false, "expected exception calling __defineGetter__ with only one arg"); + }catch(e) { + ok(e.number === 0xa138a - 0x80000000, "__defineGetter__ with only one arg threw exception " + e.number); + } + + x.bar = "test"; + ok(x.bar === "test", "x.bar = " + x.bar); + x.__defineGetter__("bar", getter); + ok(x.bar === "wine", "x.bar with getter = " + x.bar); +}); + async_test("postMessage", function() { var v = document.documentMode; var onmessage_called = false;
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/object.c | 44 ++++++++++++++ dlls/mshtml/tests/documentmode.js | 95 +++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+)
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index d7650ff..bf0be64 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -337,6 +337,49 @@ done: return S_OK; }
+static HRESULT Object_defineSetter(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) +{ + property_desc_t desc; + const WCHAR *name; + jsstr_t *name_str; + jsdisp_t *jsthis; + HRESULT hres; + + TRACE("\n"); + + if(!is_object_instance(vthis) || !(jsthis = to_jsdisp(get_object(vthis)))) + goto done; + + if(argc < 2 || !is_object_instance(argv[1])) + return JS_E_FUNCTION_EXPECTED; + + desc.setter = to_jsdisp(get_object(argv[1])); + if(!desc.setter) { + FIXME("setter is not JS object\n"); + return E_NOTIMPL; + } + /* FIXME: Check IsCallable */ + + hres = to_flat_string(ctx, argv[0], &name_str, &name); + if(FAILED(hres)) + return hres; + + desc.flags = desc.mask = PROPF_CONFIGURABLE | PROPF_ENUMERABLE; + desc.explicit_getter = FALSE; + desc.explicit_setter = TRUE; + desc.explicit_value = FALSE; + desc.getter = NULL; + hres = jsdisp_define_property(jsthis, name, &desc); + + jsstr_release(name_str); + if(FAILED(hres)) + return hres; +done: + if(r) + *r = jsval_undefined(); + return S_OK; +} + HRESULT Object_get_proto_(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis; @@ -409,6 +452,7 @@ static void Object_destructor(jsdisp_t *dispex)
static const builtin_prop_t Object_props[] = { {L"__defineGetter__", Object_defineGetter, PROPF_METHOD|PROPF_ES6|2}, + {L"__defineSetter__", Object_defineSetter, PROPF_METHOD|PROPF_ES6|2}, {L"hasOwnProperty", Object_hasOwnProperty, PROPF_METHOD|1}, {L"isPrototypeOf", Object_isPrototypeOf, PROPF_METHOD|1}, {L"propertyIsEnumerable", Object_propertyIsEnumerable, PROPF_METHOD|1}, diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 18dd65e..4a776f8 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1503,6 +1503,101 @@ sync_test("__defineGetter__", function() { ok(x.bar === "wine", "x.bar with getter = " + x.bar); });
+sync_test("__defineSetter__", function() { + var v = document.documentMode; + var r, x = 42; + + if(v < 11) { + ok(x.__defineSetter__ === undefined, "x.__defineSetter__ = " + x.__defineSetter__); + ok(!("__defineSetter__" in Object), "Object.__defineSetter__ = " + Object.__defineSetter__); + return; + } + ok(Object.prototype.hasOwnProperty("__defineSetter__"), "__defineSetter__ is not a property of Object.prototype"); + ok(Object.prototype.__defineSetter__.length === 2, "__defineSetter__.length = " + Object.prototype.__defineSetter__.length); + + function getter() { return "wine"; } + function setter(val) { this.setterVal = val - 1; } + + r = x.__defineSetter__("foo", setter); + ok(r === undefined, "__defineSetter__ on 42 returned " + r); + ok(x.foo === undefined, "42.foo = " + x.foo); + + x = {}; + r = x.__defineSetter__("foo", setter); + ok(r === undefined, "__defineSetter__ returned " + r); + ok(x.setterVal === undefined, "x.setterVal = " + x.setterVal); + x.foo = 13; + ok(x.setterVal === 12, "x.setterVal = " + x.setterVal); + r = Object.getOwnPropertyDescriptor(x, "foo"); + ok(r.value === undefined, "x.foo value = " + r.value); + ok(r.get === undefined, "x.foo get = " + r.get); + ok(r.set === setter, "x.foo set = " + r.set); + ok(r.writable === undefined, "x.foo writable = " + r.writable); + ok(r.enumerable === true, "x.foo enumerable = " + r.enumerable); + ok(r.configurable === true, "x.foo configurable = " + r.configurable); + + Object.defineProperty(x, "foo", { get: getter, set: undefined, configurable: false }); + r = Object.getOwnPropertyDescriptor(x, "foo"); + ok(r.value === undefined, "x.foo getter value = " + r.value); + ok(r.get === getter, "x.foo getter get = " + r.get); + ok(r.set === undefined, "x.foo getter set = " + r.set); + ok(r.writable === undefined, "x.foo getter writable = " + r.writable); + ok(r.enumerable === true, "x.foo getter enumerable = " + r.enumerable); + ok(r.configurable === false, "x.foo getter configurable = " + r.configurable); + try { + x.__defineSetter__("foo", setter); + ok(false, "expected exception calling __defineSetter__ on non-configurable property"); + }catch(e) { + ok(e.number === 0xa13d6 - 0x80000000, "__defineSetter__ on non-configurable property threw exception " + e.number); + } + + r = Object.prototype.__defineSetter__.call(undefined, "bar", setter); + ok(r === undefined, "__defineSetter__ on undefined returned " + r); + r = Object.prototype.__defineSetter__.call(null, "bar", setter); + ok(r === undefined, "__defineSetter__ on null returned " + r); + r = x.__defineSetter__(null, setter); + ok(r === undefined, "__defineSetter__ null prop returned " + r); + x["null"] = 100; + ok(x.setterVal === 99, "x.setterVal after setting x.null = " + x.setterVal); + r = x.__defineSetter__(50, setter); + ok(r === undefined, "__defineSetter__ 50 prop returned " + r); + x["50"] = 33; + ok(x.setterVal === 32, "x.setterVal after setting x.50 = " + x.setterVal); + + try { + x.__defineSetter__("bar", true); + ok(false, "expected exception calling __defineSetter__ with bool"); + }catch(e) { + ok(e.number === 0xa138a - 0x80000000, "__defineSetter__ with bool threw exception " + e.number); + } + try { + x.__defineSetter__("bar", undefined); + ok(false, "expected exception calling __defineSetter__ with undefined"); + }catch(e) { + ok(e.number === 0xa138a - 0x80000000, "__defineSetter__ with undefined threw exception " + e.number); + } + try { + x.__defineSetter__("bar", null); + ok(false, "expected exception calling __defineSetter__ with null"); + }catch(e) { + ok(e.number === 0xa138a - 0x80000000, "__defineSetter__ with null threw exception " + e.number); + } + try { + Object.prototype.__defineSetter__.call(x, "bar"); + ok(false, "expected exception calling __defineSetter__ with only one arg"); + }catch(e) { + ok(e.number === 0xa138a - 0x80000000, "__defineSetter__ with only one arg threw exception " + e.number); + } + + x.bar = "test"; + ok(x.bar === "test", "x.bar = " + x.bar); + x.__defineSetter__("bar", setter); + ok(x.bar === undefined, "x.bar with setter = " + x.bar); + x.bar = 10; + ok(x.bar === undefined, "x.bar with setter = " + x.bar); + ok(x.setterVal === 9, "x.setterVal after setting bar = " + x.setterVal); +}); + async_test("postMessage", function() { var v = document.documentMode; var onmessage_called = false;
Signed-off-by: Jacek Caban jacek@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111277
Your paranoid android.
=== w10pro64 (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
=== w7u_adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1648227070493 expected 1648227070543"
According to the ES6 spec, they don't throw anymore (compared to ES5), but native IE seems to not follow it here and throws anyway.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/object.c | 18 ++++++------------ dlls/mshtml/tests/documentmode.js | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index bf0be64..d1522b1 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -844,10 +844,8 @@ static HRESULT Object_getPrototypeOf(script_ctx_t *ctx, jsval_t vthis, WORD flag { jsdisp_t *obj;
- if(!argc || !is_object_instance(argv[0])) { - FIXME("invalid arguments\n"); - return E_NOTIMPL; - } + if(!argc || !is_object_instance(argv[0])) + return JS_E_OBJECT_EXPECTED;
TRACE("(%s)\n", debugstr_jsval(argv[0]));
@@ -872,10 +870,8 @@ static HRESULT object_keys(script_ctx_t *ctx, jsval_t arg, enum jsdisp_enum_type jsstr_t *key; HRESULT hres;
- if(!is_object_instance(arg)) { - FIXME("invalid arguments %s\n", debugstr_jsval(arg)); - return E_NOTIMPL; - } + if(!is_object_instance(arg)) + return JS_E_OBJECT_EXPECTED;
obj = to_jsdisp(get_object(arg)); if(!obj) { @@ -931,10 +927,8 @@ static HRESULT Object_preventExtensions(script_ctx_t *ctx, jsval_t vthis, WORD f { jsdisp_t *obj;
- if(!argc || !is_object_instance(argv[0])) { - FIXME("invalid arguments\n"); - return E_NOTIMPL; - } + if(!argc || !is_object_instance(argv[0])) + return JS_E_OBJECT_EXPECTED;
TRACE("(%s)\n", debugstr_jsval(argv[0]));
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 4a776f8..b4d0beb 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1278,6 +1278,30 @@ sync_test("elem_attr", function() { } });
+sync_test("builtins_diffs", function() { + var v = document.documentMode; + + /* despite what spec says for ES6, IE still throws */ + var props = [ + "freeze", + "getPrototypeOf", + "isExtensible", + "isFrozen", + "isSealed", + "keys", + "preventExtensions", + "seal" + ]; + for(var i = 0; i < props.length; i++) { + try { + Object[props[i]]("test"); + ok(false, "Object." + props[i] + " with non-object: expected exception"); + }catch(e) { + ok(e.number === (v < 9 ? 0xa01b6 : 0xa138f) - 0x80000000, "Object." + props[i] + " with non-object: exception = " + e.number); + } + } +}); + sync_test("__proto__", function() { var v = document.documentMode; var r, x = 42;
Signed-off-by: Jacek Caban jacek@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111278
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1648229168557 expected 1648229168620"
=== w7u_adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1648228752547 expected 1648228752604"
=== w7u_el (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1648228649130 expected 1648228649182"
According to the ES6 spec, it should work in generic way for objects exposing "source" and "flags", but native IE seems to not follow it here and throws.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
FFXIV Launcher checks for this.
dlls/mshtml/tests/documentmode.js | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index b4d0beb..3f772cf 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1300,6 +1300,13 @@ sync_test("builtins_diffs", function() { ok(e.number === (v < 9 ? 0xa01b6 : 0xa138f) - 0x80000000, "Object." + props[i] + " with non-object: exception = " + e.number); } } + + try { + RegExp.prototype.toString.call({source: "foo", flags: "g"}); + ok(false, "RegExp.toString with non-regexp: expected exception"); + }catch(e) { + ok(e.number === 0xa1398 - 0x80000000, "RegExp.toString with non-regexp: exception = " + e.number); + } });
sync_test("__proto__", function() {
Signed-off-by: Jacek Caban jacek@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111279
Your paranoid android.
=== w8 (32 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w10pro64_ar (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
=== w7u_adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1648231775350 expected 1648231775412"
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/object.c | 7 +------ dlls/mshtml/tests/es5.js | 2 ++ 2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index d1522b1..a675e45 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -850,13 +850,8 @@ static HRESULT Object_getPrototypeOf(script_ctx_t *ctx, jsval_t vthis, WORD flag TRACE("(%s)\n", debugstr_jsval(argv[0]));
obj = to_jsdisp(get_object(argv[0])); - if(!obj) { - FIXME("Non-JS object\n"); - return E_NOTIMPL; - } - if(r) - *r = obj->prototype + *r = obj && obj->prototype ? jsval_obj(jsdisp_addref(obj->prototype)) : jsval_null(); return S_OK; diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index c03a2c2..0339d9b 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -803,6 +803,8 @@ sync_test("getPrototypeOf", function() { obj = Object.create(null); ok(!("toString" in obj), "toString is in obj"); ok(Object.getPrototypeOf(obj) === null, "Object.getPrototypeOf(obj) = " + Object.getPrototypeOf(obj)); + + ok(Object.getPrototypeOf(external) === null, "Object.getPrototypeOf(non-JS obj) = " + Object.getPrototypeOf(external)); });
sync_test("toString", function() {
Signed-off-by: Jacek Caban jacek@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111280
Your paranoid android.
=== w8adm (32 bit report) ===
mshtml: events.c:1089: Test failed: unexpected call img_onerror events: Timeout
=== w10pro64_ja (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Tested in the next patch (we use the test_own_data_prop_desc helper to avoid redundancy, which also checks enumerable).
dlls/jscript/dispex.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index ef13e29..32265d3 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2546,6 +2546,7 @@ HRESULT jsdisp_get_own_property(jsdisp_t *obj, const WCHAR *name, BOOL flags_onl switch(prop->type) { case PROP_BUILTIN: case PROP_JSVAL: + case PROP_IDX: desc->mask |= PROPF_WRITABLE; desc->explicit_value = TRUE; if(!flags_only) {
Hi Jacek,
Any news about these 2 patches?
Hi Gabriel,
On 4/8/22 16:37, Gabriel Ivăncescu wrote:
Hi Jacek,
Any news about these 2 patches?
They look mostly good, but it looks like TestBot is not happy with those tests. Also, is there a reason to use Object.prototype.hasOwnProperty.call(s,"...") instead of simply s.hasOwnProperty(s, "...")?
Thanks,
Jacek
On 11/04/2022 13:22, Jacek Caban wrote:
Hi Gabriel,
On 4/8/22 16:37, Gabriel Ivăncescu wrote:
Hi Jacek,
Any news about these 2 patches?
They look mostly good, but it looks like TestBot is not happy with those tests. Also, is there a reason to use Object.prototype.hasOwnProperty.call(s,"...") instead of simply s.hasOwnProperty(s, "...")?
Thanks,
Jacek
That looks like a bug in Windows 8's mshtml jscript engine, I can't explain it in any other way (and why it happens only on Windows 8 VMs). Should I leave the test out? I don't know how to mark it as broken for Windows-only in js tests.
And sorry about the Object.prototype.hasOwnProperty, it's just a habit when I write tests so I know exactly what it's tested (bypassing any overrides in the prototype chain). There's no other reason. I know I changed it before, but I either keep forgetting to change them all or keep rewriting it :-/
Signed-off-by: Gabriel Ivăncescu gabrielopcode@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() {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111282
Your paranoid android.
=== w10pro64_he (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
=== w7u_adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1648236542908 expected 1648236542971"
=== w8 (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:string_idx: '7' not a property"
=== w8adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:string_idx: '7' not a property"
=== w864 (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:string_idx: '7' not a property"
=== w864 (64 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:string_idx: '7' not a property"
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=111276
Your paranoid android.
=== w10pro64_ar (64 bit report) ===
mshtml: htmldoc.c:2541: Test failed: unexpected call UpdateUI htmldoc.c:2853: Test failed: unexpected call Exec_UPDATECOMMANDS
=== w7u_adm (32 bit report) ===
mshtml: script.c:624: Test failed: L"/index.html?es5.js:date_now: unexpected Date.now() result 1648224121251 expected 1648224121305"