[PATCH 5/5] jscript: Don't allow changing prototype on non-extensible objects.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Mar 21 10:58:32 CDT 2022


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/jscript/dispex.c             |  2 ++
 dlls/jscript/error.c              |  1 +
 dlls/jscript/jscript.h            |  1 +
 dlls/jscript/jscript.rc           |  1 +
 dlls/jscript/resource.h           |  1 +
 dlls/mshtml/tests/documentmode.js | 10 ++++++++++
 6 files changed, 16 insertions(+)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index eff91e9..df2f65f 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -2713,6 +2713,8 @@ HRESULT jsdisp_change_prototype(jsdisp_t *obj, jsdisp_t *proto)
 
     if(obj->prototype == proto)
         return S_OK;
+    if(!obj->extensible)
+        return JS_E_CANNOT_CREATE_FOR_NONEXTENSIBLE;
 
     for(iter = proto; iter; iter = iter->prototype)
         if(iter == obj)
diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c
index 4db95e5..d309d42 100644
--- a/dlls/jscript/error.c
+++ b/dlls/jscript/error.c
@@ -478,6 +478,7 @@ jsdisp_t *create_builtin_error(script_ctx_t *ctx)
         case JS_E_REGEXP_EXPECTED:
         case JS_E_ARRAY_EXPECTED:
         case JS_E_CYCLIC_PROTO_VALUE:
+        case JS_E_CANNOT_CREATE_FOR_NONEXTENSIBLE:
         case JS_E_OBJECT_NONEXTENSIBLE:
         case JS_E_NONCONFIGURABLE_REDEFINED:
         case JS_E_NONWRITABLE_MODIFIED:
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 96f2270..7ed4425 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -519,6 +519,7 @@ static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
 #define JS_E_INVALID_LENGTH          MAKE_JSERROR(IDS_INVALID_LENGTH)
 #define JS_E_ARRAY_EXPECTED          MAKE_JSERROR(IDS_ARRAY_EXPECTED)
 #define JS_E_CYCLIC_PROTO_VALUE      MAKE_JSERROR(IDS_CYCLIC_PROTO_VALUE)
+#define JS_E_CANNOT_CREATE_FOR_NONEXTENSIBLE MAKE_JSERROR(IDS_CREATE_FOR_NONEXTENSIBLE)
 #define JS_E_OBJECT_NONEXTENSIBLE    MAKE_JSERROR(IDS_OBJECT_NONEXTENSIBLE)
 #define JS_E_NONCONFIGURABLE_REDEFINED MAKE_JSERROR(IDS_NONCONFIGURABLE_REDEFINED)
 #define JS_E_NONWRITABLE_MODIFIED    MAKE_JSERROR(IDS_NONWRITABLE_MODIFIED)
diff --git a/dlls/jscript/jscript.rc b/dlls/jscript/jscript.rc
index 38a49d9..c931eef 100644
--- a/dlls/jscript/jscript.rc
+++ b/dlls/jscript/jscript.rc
@@ -71,6 +71,7 @@ STRINGTABLE
     IDS_ARRAY_EXPECTED      "Array object expected"
     IDS_INVALID_WRITABLE_PROP_DESC "'writable' attribute on the property descriptor cannot be set to 'true' on this object"
     IDS_CYCLIC_PROTO_VALUE         "Cyclic __proto__ value"
+    IDS_CREATE_FOR_NONEXTENSIBLE   "Cannot create property for a non-extensible object"
     IDS_OBJECT_NONEXTENSIBLE       "Cannot define property '|': object is not extensible"
     IDS_NONCONFIGURABLE_REDEFINED  "Cannot redefine non-configurable property '|'"
     IDS_NONWRITABLE_MODIFIED       "Cannot modify non-writable property '|'"
diff --git a/dlls/jscript/resource.h b/dlls/jscript/resource.h
index 0793431..1338ac5 100644
--- a/dlls/jscript/resource.h
+++ b/dlls/jscript/resource.h
@@ -69,6 +69,7 @@
 #define IDS_ARRAY_EXPECTED                  0x13A7
 #define IDS_INVALID_WRITABLE_PROP_DESC      0x13AC
 #define IDS_CYCLIC_PROTO_VALUE              0x13B0
+#define IDS_CREATE_FOR_NONEXTENSIBLE        0x13B6
 #define IDS_OBJECT_NONEXTENSIBLE            0x13D5
 #define IDS_NONCONFIGURABLE_REDEFINED       0x13D6
 #define IDS_NONWRITABLE_MODIFIED            0x13D7
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 51a8fe0..2902902 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -1403,6 +1403,16 @@ sync_test("__proto__", function() {
         ok(e.number === 0xa13b0 - 0x80000000 && e.name === "TypeError",
             "setting circular proto chain threw exception " + e.number + " (" + e.name + ")");
     }
+
+    Object.preventExtensions(x);
+    x.__proto__ = Object.prototype;  /* same prototype */
+    try {
+        x.__proto__ = Number.prototype;
+        ok(false, "expected exception changing __proto__ on non-extensible object");
+    }catch(e) {
+        ok(e.number === 0xa13b6 - 0x80000000 && e.name === "TypeError",
+            "changing __proto__ on non-extensible object threw exception " + e.number + " (" + e.name + ")");
+    }
 });
 
 async_test("postMessage", function() {
-- 
2.34.1




More information about the wine-devel mailing list