Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
v2: Add tests.
dlls/jscript/dispex.c | 2 +- dlls/jscript/tests/lang.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 5829ceb..9d0357e 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1853,7 +1853,7 @@ HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const built return hres; }
- if(is_object_instance(val)) + if(is_object_instance(val) && get_object(val)) prot = iface_to_jsdisp(get_object(val)); jsval_release(val); } diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 753b4ee..211ae2f 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -1864,6 +1864,21 @@ ok(tmp === "VT_DISPATCH", "getVT(Object(nullDisp) = " + tmp); tmp = Object(nullDisp).toString(); ok(tmp === "[object Object]", "Object(nullDisp).toString() = " + tmp);
+function testNullPrototype() { + this.x = 13; +} +tmp = new testNullPrototype(); +ok(tmp.x === 13, "tmp.x !== 13"); +ok(!("y" in tmp), "tmp has 'y' property"); +testNullPrototype.prototype.y = 10; +ok("y" in tmp, "tmp does not have 'y' property"); +tmp = new testNullPrototype(); +ok(tmp.y === 10, "tmp.y !== 10"); +testNullPrototype.prototype = nullDisp; +tmp = new testNullPrototype(); +ok(tmp.x === 13, "tmp.x !== 13"); +ok(!("y" in tmp), "tmp has 'y' property"); + function do_test() {} function nosemicolon() {} nosemicolon(); function () {} nosemicolon();
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 4 ++++ dlls/jscript/tests/lang.js | 8 ++++++++ 2 files changed, 12 insertions(+)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 9d0357e..d5d6912 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -1855,6 +1855,10 @@ HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const built
if(is_object_instance(val) && get_object(val)) prot = iface_to_jsdisp(get_object(val)); + else if(SUCCEEDED(find_prop_name(ctx->object_constr, string_hash(L"prototype"), L"prototype", &prop)) && + prop && prop->type != PROP_DELETED && SUCCEEDED(prop_get(constr, prop, &val)) && is_object_instance(val)) + prot = iface_to_jsdisp(get_object(val)); + jsval_release(val); }
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 211ae2f..94c3329 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -1878,6 +1878,14 @@ testNullPrototype.prototype = nullDisp; tmp = new testNullPrototype(); ok(tmp.x === 13, "tmp.x !== 13"); ok(!("y" in tmp), "tmp has 'y' property"); +ok(!tmp.hasOwnProperty("y"), "tmp has 'y' property"); +ok(!tmp.propertyIsEnumerable("y"), "tmp has 'y' property enumerable"); +ok(tmp.toString() == "[object Object]", "tmp.toString returned " + tmp.toString()); +testNullPrototype.prototype = null; +tmp = new testNullPrototype(); +ok(!tmp.hasOwnProperty("y"), "tmp has 'y' property"); +ok(!tmp.propertyIsEnumerable("y"), "tmp has 'y' property enumerable"); +ok(tmp.toString() == "[object Object]", "tmp.toString returned " + tmp.toString());
function do_test() {} function nosemicolon() {} nosemicolon();
Hi Gabriel,
On 05.03.2021 17:59, Gabriel Ivăncescu wrote:
else if(SUCCEEDED(find_prop_name(ctx->object_constr, string_hash(L"prototype"), L"prototype", &prop)) &&
prop && prop->type != PROP_DELETED && SUCCEEDED(prop_get(constr, prop, &val)) && is_object_instance(val))
prot = iface_to_jsdisp(get_object(val));
We should probably just store object prototype in script_ctx_t. Note that if some weird script replaces Object.prototype value, we still want to use builtin one instead.
Also some tests using different prototype types would be nice, for example you may try to set it to number, boolean and a string.
Thanks,
Jacek