Jacek Caban : jscript: Support non-extensible objects.

Alexandre Julliard julliard at winehq.org
Thu Apr 1 16:09:30 CDT 2021


Module: wine
Branch: master
Commit: 7750753758693cbd09b978dfb53557c3b0715335
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=7750753758693cbd09b978dfb53557c3b0715335

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Apr  1 18:18:40 2021 +0200

jscript: Support non-extensible objects.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/dispex.c    | 12 +++++++++---
 dlls/jscript/jscript.h   |  1 +
 dlls/jscript/object.c    |  3 ++-
 dlls/mshtml/tests/es5.js |  8 +++++++-
 4 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 0f0907063f8..303e5bb8c99 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -474,6 +474,8 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val)
         return prop->u.p->setter(This->ctx, This, val);
     case PROP_PROTREF:
     case PROP_DELETED:
+        if(!This->extensible)
+            return S_OK;
         prop->type = PROP_JSVAL;
         prop->flags = PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE;
         prop->u.val = jsval_undefined();
@@ -1747,6 +1749,7 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b
     dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl;
     dispex->ref = 1;
     dispex->builtin_info = builtin_info;
+    dispex->extensible = TRUE;
 
     dispex->props = heap_alloc_zero(sizeof(dispex_prop_t)*(dispex->buf_size=4));
     if(!dispex->props)
@@ -1894,7 +1897,7 @@ HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *
     dispex_prop_t *prop;
     HRESULT hres;
 
-    if(flags & fdexNameEnsure)
+    if(jsdisp->extensible && (flags & fdexNameEnsure))
         hres = ensure_prop_name(jsdisp, name, PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE,
                                 &prop);
     else
@@ -2147,8 +2150,11 @@ HRESULT jsdisp_propput(jsdisp_t *obj, const WCHAR *name, DWORD flags, jsval_t va
     dispex_prop_t *prop;
     HRESULT hres;
 
-    hres = ensure_prop_name(obj, name, flags, &prop);
-    if(FAILED(hres))
+    if(obj->extensible)
+        hres = ensure_prop_name(obj, name, flags, &prop);
+    else
+        hres = find_prop_name_prot(obj, string_hash(name), name, &prop);
+    if(FAILED(hres) || !prop)
         return hres;
 
     return prop_put(obj, prop, val);
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index c8ec7622caf..f27f660d802 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -247,6 +247,7 @@ struct jsdisp_t {
     DWORD prop_cnt;
     dispex_prop_t *props;
     script_ctx_t *ctx;
+    BOOL extensible;
 
     jsdisp_t *prototype;
 
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c
index 1e94f163446..da91b744128 100644
--- a/dlls/jscript/object.c
+++ b/dlls/jscript/object.c
@@ -680,7 +680,7 @@ static HRESULT Object_preventExtensions(script_ctx_t *ctx, vdisp_t *jsthis, WORD
         return E_NOTIMPL;
     }
 
-    FIXME("(%s) semi-stub\n", debugstr_jsval(argv[0]));
+    TRACE("(%s)\n", debugstr_jsval(argv[0]));
 
     obj = to_jsdisp(get_object(argv[0]));
     if(!obj) {
@@ -688,6 +688,7 @@ static HRESULT Object_preventExtensions(script_ctx_t *ctx, vdisp_t *jsthis, WORD
         return E_NOTIMPL;
     }
 
+    obj->extensible = FALSE;
     if(r) *r = jsval_obj(jsdisp_addref(obj));
     return S_OK;
 }
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index e8c523b0bf7..3eccc38fada 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -947,7 +947,6 @@ sync_test("preventExtensions", function() {
     var r = Object.preventExtensions(o);
     ok(r === o, "r != o");
     o.x = 1;
-    todo_wine.
     ok(!("x" in o), "x property added to o");
     try {
         Object.defineProperty(o, "y", { value: true });
@@ -960,6 +959,13 @@ sync_test("preventExtensions", function() {
     r = Object.preventExtensions(o);
     ok(r === o, "r != o");
 
+    function Constr() {}
+    o = Object.preventExtensions(new Constr());
+    Constr.prototype.prop = 1;
+    ok(o.prop === 1, "o.prop = " + o.prop);
+    o.prop = 2;
+    ok(o.prop === 1, "o.prop = " + o.prop);
+
     ok(Object.preventExtensions.length === 1, "Object.preventExtensions.length = " + Object.preventExtensions.length);
 });
 




More information about the wine-cvs mailing list