[JSC] Consider dropping JSObjectSetPrototype feature for JSGlobalObject
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Sep 2017 20:06:34 +0000 (20:06 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Sep 2017 20:06:34 +0000 (20:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177070

Reviewed by Saam Barati.

Due to the security reason, our global object is immutable prototype exotic object.
It prevents users from injecting proxies into the prototype chain of the global object[1].
But our JSC API does not respect this attribute, and allows users to change [[Prototype]]
of the global object after instantiating it.

This patch removes this feature. Once global object is instantiated, we cannot change [[Prototype]]
of the global object. It drops JSGlobalObject::resetPrototype use, which involves GlobalThis
edge cases.

[1]: https://github.com/tc39/ecma262/commit/935dad4283d045bc09c67a259279772d01b3d33d

* API/JSObjectRef.cpp:
(JSObjectSetPrototype):
* API/tests/CustomGlobalObjectClassTest.c:
(globalObjectSetPrototypeTest):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222175 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/API/JSObjectRef.cpp
Source/JavaScriptCore/API/tests/CustomGlobalObjectClassTest.c
Source/JavaScriptCore/ChangeLog

index 249b554..790f8ab 100644 (file)
@@ -267,16 +267,8 @@ void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value
 
     JSObject* jsObject = toJS(object);
     JSValue jsValue = toJS(exec, value);
-
-    if (JSProxy* proxy = jsDynamicCast<JSProxy*>(vm, jsObject)) {
-        if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(vm, proxy->target())) {
-            globalObject->resetPrototype(vm, jsValue.isObject() ? jsValue : jsNull());
-            return;
-        }
-        // Someday we might use proxies for something other than JSGlobalObjects, but today is not that day.
-        RELEASE_ASSERT_NOT_REACHED();
-    }
     jsObject->setPrototype(vm, exec, jsValue.isObject() ? jsValue : jsNull());
+    handleExceptionIfNeeded(exec, nullptr);
 }
 
 bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
index 976a881..ac5471a 100644 (file)
@@ -110,19 +110,11 @@ void globalObjectSetPrototypeTest()
     JSGlobalContextRef context = JSGlobalContextCreate(global);
     JSObjectRef object = JSContextGetGlobalObject(context);
 
+    JSValueRef originalPrototype = JSObjectGetPrototype(context, object);
     JSObjectRef above = JSObjectMake(context, 0, 0);
-    JSStringRef test = JSStringCreateWithUTF8CString("test");
-    JSValueRef value = JSValueMakeString(context, test);
-    JSObjectSetProperty(context, above, test, value, kJSPropertyAttributeDontEnum, 0);
-
     JSObjectSetPrototype(context, object, above);
-    JSStringRef script = JSStringCreateWithUTF8CString("test === \"test\"");
-    JSValueRef result = JSEvaluateScript(context, script, 0, 0, 0, 0);
-
-    assertTrue(JSValueToBoolean(context, result), "test === \"test\"");
-
-    JSStringRelease(test);
-    JSStringRelease(script);
+    JSValueRef prototypeAfterChangingAttempt = JSObjectGetPrototype(context, object);
+    assertTrue(JSValueIsStrictEqual(context, prototypeAfterChangingAttempt, originalPrototype), "Global object's [[Prototype]] cannot be changed after instantiating it");
 }
 
 void globalObjectPrivatePropertyTest()
index 2dc1062..cfc3b0e 100644 (file)
@@ -1,3 +1,26 @@
+2017-09-18  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [JSC] Consider dropping JSObjectSetPrototype feature for JSGlobalObject
+        https://bugs.webkit.org/show_bug.cgi?id=177070
+
+        Reviewed by Saam Barati.
+
+        Due to the security reason, our global object is immutable prototype exotic object.
+        It prevents users from injecting proxies into the prototype chain of the global object[1].
+        But our JSC API does not respect this attribute, and allows users to change [[Prototype]]
+        of the global object after instantiating it.
+
+        This patch removes this feature. Once global object is instantiated, we cannot change [[Prototype]]
+        of the global object. It drops JSGlobalObject::resetPrototype use, which involves GlobalThis
+        edge cases.
+
+        [1]: https://github.com/tc39/ecma262/commit/935dad4283d045bc09c67a259279772d01b3d33d
+
+        * API/JSObjectRef.cpp:
+        (JSObjectSetPrototype):
+        * API/tests/CustomGlobalObjectClassTest.c:
+        (globalObjectSetPrototypeTest):
+
 2017-09-17  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [DFG] Remove ToThis more aggressively