Gabriel Ivăncescu : jscript: Throw error when attempting to set circular __proto__ chains.

Alexandre Julliard julliard at winehq.org
Mon Mar 21 17:20:26 CDT 2022


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

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Mon Mar 21 17:58:31 2022 +0200

jscript: Throw error when attempting to set circular __proto__ chains.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/dispex.c             |  5 +++++
 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 | 13 +++++++++++++
 6 files changed, 22 insertions(+)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index a74840ef701..eff91e93bbf 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -2708,11 +2708,16 @@ HRESULT jsdisp_define_data_property(jsdisp_t *obj, const WCHAR *name, unsigned f
 
 HRESULT jsdisp_change_prototype(jsdisp_t *obj, jsdisp_t *proto)
 {
+    jsdisp_t *iter;
     DWORD i;
 
     if(obj->prototype == proto)
         return S_OK;
 
+    for(iter = proto; iter; iter = iter->prototype)
+        if(iter == obj)
+            return JS_E_CYCLIC_PROTO_VALUE;
+
     if(obj->prototype) {
         for(i = 0; i < obj->prop_cnt; i++)
             if(obj->props[i].type == PROP_PROTREF)
diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c
index 6f17699a210..4db95e5f9fe 100644
--- a/dlls/jscript/error.c
+++ b/dlls/jscript/error.c
@@ -477,6 +477,7 @@ jsdisp_t *create_builtin_error(script_ctx_t *ctx)
         case JS_E_ENUMERATOR_EXPECTED:
         case JS_E_REGEXP_EXPECTED:
         case JS_E_ARRAY_EXPECTED:
+        case JS_E_CYCLIC_PROTO_VALUE:
         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 4a4d303f563..96f2270ad98 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -518,6 +518,7 @@ static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
 #define JS_E_PRECISION_OUT_OF_RANGE  MAKE_JSERROR(IDS_PRECISION_OUT_OF_RANGE)
 #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_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 50e2c30700e..38a49d9b850 100644
--- a/dlls/jscript/jscript.rc
+++ b/dlls/jscript/jscript.rc
@@ -70,6 +70,7 @@ STRINGTABLE
     IDS_INVALID_LENGTH      "Array length must be a finite positive integer"
     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_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 b17f9fbd561..07934311a1b 100644
--- a/dlls/jscript/resource.h
+++ b/dlls/jscript/resource.h
@@ -68,6 +68,7 @@
 #define IDS_INVALID_LENGTH                  0x13A5
 #define IDS_ARRAY_EXPECTED                  0x13A7
 #define IDS_INVALID_WRITABLE_PROP_DESC      0x13AC
+#define IDS_CYCLIC_PROTO_VALUE              0x13B0
 #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 43ebd56eb7e..51a8fe0f877 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -1390,6 +1390,19 @@ sync_test("__proto__", function() {
     }catch(e) {
         ok(e.number === 0xa138f - 0x80000000, "calling __proto__ setter on null threw exception " + e.number);
     }
+
+    x = {};
+    r = Object.create(x);
+    ok(r.__proto__ === x, "r.__proto__ = " + r.__proto__);
+    r = Object.create(r);
+    ok(r.__proto__.__proto__ === x, "r.__proto__.__proto__ = " + r.__proto__.__proto__);
+    try {
+        x.__proto__ = r;
+        ok(false, "expected exception setting circular proto chain");
+    }catch(e) {
+        ok(e.number === 0xa13b0 - 0x80000000 && e.name === "TypeError",
+            "setting circular proto chain threw exception " + e.number + " (" + e.name + ")");
+    }
 });
 
 async_test("postMessage", function() {




More information about the wine-cvs mailing list