[PATCH 4/5] jscript: Throw error when attempting to set circular __proto__ chains.

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


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 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 a74840e..eff91e9 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 6f17699..4db95e5 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 4a4d303..96f2270 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 50e2c30..38a49d9 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 b17f9fb..0793431 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 43ebd56..51a8fe0 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() {
-- 
2.34.1




More information about the wine-devel mailing list