Title: [206966] trunk
Revision
206966
Author
commit-qu...@webkit.org
Date
2016-10-09 00:34:08 -0700 (Sun, 09 Oct 2016)

Log Message

Promise attribute getters should reject promises in case of casted-this errors
https://bugs.webkit.org/show_bug.cgi?id=163167

Patch by Youenn Fablet <you...@apple.com> on 2016-10-09
Reviewed by Darin Adler.

Source/WebCore:

Covered by updated test and binding test.

* bindings/js/JSDOMBinding.cpp:
(WebCore::throwGetterTypeError):
(WebCore::rejectPromiseWithGetterTypeError): Added to reject promises for attribute getters
* bindings/js/JSDOMBinding.h:
(WebCore::BindingCaller::attribute): Introducing promise rejection for type cast errors.
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
* bindings/scripts/test/JS/JSTestObj.cpp: Rebased test. As can be seen, only custom promise attributes are supported.
(WebCore::jsTestObjTestReadOnlyPromiseAttribute):
(WebCore::jsTestObjTestReadOnlyPromiseAttributeGetter):
* bindings/scripts/test/TestObj.idl:

LayoutTests:

* fast/text/font-face-set-_javascript_-expected.txt:
* fast/text/font-face-set-_javascript_.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (206965 => 206966)


--- trunk/LayoutTests/ChangeLog	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/LayoutTests/ChangeLog	2016-10-09 07:34:08 UTC (rev 206966)
@@ -1,3 +1,13 @@
+2016-10-09  Youenn Fablet  <you...@apple.com>
+
+        Promise attribute getters should reject promises in case of casted-this errors
+        https://bugs.webkit.org/show_bug.cgi?id=163167
+
+        Reviewed by Darin Adler.
+
+        * fast/text/font-face-set-_javascript_-expected.txt:
+        * fast/text/font-face-set-_javascript_.html:
+
 2016-10-08  Chris Dumez  <cdu...@apple.com>
 
         [Mac] Write HTML to the pasteboard when copying image in WebKit

Modified: trunk/LayoutTests/fast/text/font-face-set-_javascript_-expected.txt (206965 => 206966)


--- trunk/LayoutTests/fast/text/font-face-set-_javascript_-expected.txt	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/LayoutTests/fast/text/font-face-set-_javascript_-expected.txt	2016-10-09 07:34:08 UTC (rev 206966)
@@ -59,6 +59,7 @@
 PASS fontFaceSet.status is "loaded"
 PASS fontFaceSet.status is "loading"
 PASS item is fontFaceSet
+PASS TypeError: The FontFaceSet.ready getter can only be used on instances of FontFaceSet
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/text/font-face-set-_javascript_.html (206965 => 206966)


--- trunk/LayoutTests/fast/text/font-face-set-_javascript_.html	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/LayoutTests/fast/text/font-face-set-_javascript_.html	2016-10-09 07:34:08 UTC (rev 206966)
@@ -163,10 +163,16 @@
 }).then(function(arg) {
     item = arg;
     shouldBe("item", "fontFaceSet");
-    finishJSTest();
 }, function(arg) {
     testFailed("Ready attribute should never fail");
+}).then(function() {
+    return Object.getOwnPropertyDescriptor(Object.getPrototypeOf(fontFaceSet), 'ready').get.apply(fontFace5);
+}).then(function(arg) {
+    testFailed("Ready attribute should be rejected when used with an object which is not FontFaceSet");
     finishJSTest();
+}, function(arg) {
+    testPassed("" + arg);
+    finishJSTest();
 });
 shouldBeEqualToString("fontFaceSet.status", "loaded");
 </script>

Modified: trunk/Source/WebCore/ChangeLog (206965 => 206966)


--- trunk/Source/WebCore/ChangeLog	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/Source/WebCore/ChangeLog	2016-10-09 07:34:08 UTC (rev 206966)
@@ -1,3 +1,24 @@
+2016-10-09  Youenn Fablet  <you...@apple.com>
+
+        Promise attribute getters should reject promises in case of casted-this errors
+        https://bugs.webkit.org/show_bug.cgi?id=163167
+
+        Reviewed by Darin Adler.
+
+        Covered by updated test and binding test.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::throwGetterTypeError):
+        (WebCore::rejectPromiseWithGetterTypeError): Added to reject promises for attribute getters
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::BindingCaller::attribute): Introducing promise rejection for type cast errors.
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateImplementation):
+        * bindings/scripts/test/JS/JSTestObj.cpp: Rebased test. As can be seen, only custom promise attributes are supported.
+        (WebCore::jsTestObjTestReadOnlyPromiseAttribute):
+        (WebCore::jsTestObjTestReadOnlyPromiseAttributeGetter):
+        * bindings/scripts/test/TestObj.idl:
+
 2016-10-08  Chris Dumez  <cdu...@apple.com>
 
         [Mac] Write WebArchive to the pasteboard when copying image in WebKit

Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (206965 => 206966)


--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp	2016-10-09 07:34:08 UTC (rev 206966)
@@ -32,6 +32,7 @@
 #include "HTMLParserIdioms.h"
 #include "IDBDatabaseException.h"
 #include "JSDOMConvert.h"
+#include "JSDOMPromise.h"
 #include "JSDOMWindowCustom.h"
 #include "JSExceptionBase.h"
 #include "SecurityOrigin.h"
@@ -973,6 +974,11 @@
     return throwVMTypeError(&state, scope, makeGetterTypeErrorMessage(interfaceName, attributeName));
 }
 
+JSC::EncodedJSValue rejectPromiseWithGetterTypeError(JSC::ExecState& state, const char* interfaceName, const char* attributeName)
+{
+    return createRejectedPromiseWithTypeError(state, makeGetterTypeErrorMessage(interfaceName, attributeName));
+}
+
 bool throwSetterTypeError(JSC::ExecState& state, JSC::ThrowScope& scope, const char* interfaceName, const char* attributeName)
 {
     throwTypeError(state, scope, makeString("The ", interfaceName, '.', attributeName, " setter can only be used on instances of ", interfaceName));

Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (206965 => 206966)


--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h	2016-10-09 07:34:08 UTC (rev 206966)
@@ -134,6 +134,8 @@
 WEBCORE_EXPORT JSC::EncodedJSValue throwGetterTypeError(JSC::ExecState&, JSC::ThrowScope&, const char* interfaceName, const char* attributeName);
 WEBCORE_EXPORT JSC::EncodedJSValue throwThisTypeError(JSC::ExecState&, JSC::ThrowScope&, const char* interfaceName, const char* functionName);
 
+JSC::EncodedJSValue rejectPromiseWithGetterTypeError(JSC::ExecState&, const char* interfaceName, const char* attributeName);
+
 WEBCORE_EXPORT JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject&, const JSC::ClassInfo*);
 WEBCORE_EXPORT JSC::Structure* cacheDOMStructure(JSDOMGlobalObject&, JSC::Structure*, const JSC::ClassInfo*);
 
@@ -329,7 +331,7 @@
 template<typename T> struct NativeValueTraits;
 
 
-enum class CastedThisErrorBehavior { Throw, ReturnEarly };
+enum class CastedThisErrorBehavior { Throw, ReturnEarly, RejectPromise };
 
 template<typename JSClass>
 struct BindingCaller {
@@ -343,8 +345,11 @@
         auto* thisObject = JSClass::castForAttribute(state, thisValue);
         if (UNLIKELY(!thisObject)) {
             ASSERT(JSClass::info());
-            return shouldThrow == CastedThisErrorBehavior::Throw ?
-                throwGetterTypeError(*state, throwScope, JSClass::info()->className, attributeName) : JSC::JSValue::encode(JSC::jsUndefined());
+            if (shouldThrow == CastedThisErrorBehavior::Throw)
+                return throwGetterTypeError(*state, throwScope, JSClass::info()->className, attributeName);
+            if (shouldThrow == CastedThisErrorBehavior::RejectPromise)
+                return rejectPromiseWithGetterTypeError(*state, JSClass::info()->className, attributeName);
+            return JSC::JSValue::encode(JSC::jsUndefined());
         }
         // FIXME: We should refactor the binding generated code to use references for state and thisObject.
         return JSC::JSValue::encode(getter(state, thisObject, throwScope));

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (206965 => 206966)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-10-09 07:34:08 UTC (rev 206966)
@@ -2920,7 +2920,12 @@
 
             if (!$attribute->isStatic || $attribute->signature->type =~ /Constructor$/) {
                 my $templateParameters = "${getFunctionName}Getter";
-                $templateParameters .= ", CastedThisErrorBehavior::ReturnEarly" if ($attribute->signature->extendedAttributes->{LenientThis});
+                if ($attribute->signature->extendedAttributes->{LenientThis}) {
+                    $templateParameters .= ", CastedThisErrorBehavior::ReturnEarly";
+                } elsif (IsReturningPromise($attribute)) {
+                    $templateParameters .= ", CastedThisErrorBehavior::RejectPromise";
+                }
+
                 push(@implContent, "static inline JSValue ${getFunctionName}Getter(ExecState*, ${className}*, ThrowScope& throwScope);\n\n");
 
                 push(@implContent, "EncodedJSValue ${getFunctionName}(ExecState* state, EncodedJSValue thisValue, PropertyName)\n");

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (206965 => 206966)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-10-09 07:34:08 UTC (rev 206966)
@@ -44,6 +44,7 @@
 #include "JSEventListener.h"
 #include "JSFetchRequest.h"
 #include "JSNode.h"
+#include "JSPromise.h"
 #include "JSSVGDocument.h"
 #include "JSSVGPoint.h"
 #include "JSTestCallback.h"
@@ -1191,6 +1192,7 @@
 JSC::EncodedJSValue jsTestObjAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 JSC::EncodedJSValue jsTestObjAttributeWithReservedEnumType(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 bool setJSTestObjAttributeWithReservedEnumType(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+JSC::EncodedJSValue jsTestObjTestReadOnlyPromiseAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 JSC::EncodedJSValue jsTestObjPutForwardsAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 bool setJSTestObjPutForwardsAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
 JSC::EncodedJSValue jsTestObjPutForwardsNullableAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
@@ -1479,6 +1481,7 @@
     { "nullableStringValue", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjNullableStringValue), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjNullableStringValue) } },
     { "attribute", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAttribute), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
     { "attributeWithReservedEnumType", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAttributeWithReservedEnumType), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjAttributeWithReservedEnumType) } },
+    { "testReadOnlyPromiseAttribute", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjTestReadOnlyPromiseAttribute), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
     { "putForwardsAttribute", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjPutForwardsAttribute), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjPutForwardsAttribute) } },
     { "putForwardsNullableAttribute", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjPutForwardsNullableAttribute), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjPutForwardsNullableAttribute) } },
     { "stringifierAttribute", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjStringifierAttribute), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjStringifierAttribute) } },
@@ -3185,6 +3188,22 @@
     return result;
 }
 
+static inline JSValue jsTestObjTestReadOnlyPromiseAttributeGetter(ExecState*, JSTestObj*, ThrowScope& throwScope);
+
+EncodedJSValue jsTestObjTestReadOnlyPromiseAttribute(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller<JSTestObj>::attribute<jsTestObjTestReadOnlyPromiseAttributeGetter, CastedThisErrorBehavior::RejectPromise>(state, thisValue, "testReadOnlyPromiseAttribute");
+}
+
+static inline JSValue jsTestObjTestReadOnlyPromiseAttributeGetter(ExecState* state, JSTestObj* thisObject, ThrowScope& throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto& impl = thisObject->wrapped();
+    JSValue result = toJS(state, thisObject->globalObject(), impl.testReadOnlyPromiseAttribute());
+    return result;
+}
+
 static inline JSValue jsTestObjPutForwardsAttributeGetter(ExecState*, JSTestObj*, ThrowScope& throwScope);
 
 EncodedJSValue jsTestObjPutForwardsAttribute(ExecState* state, EncodedJSValue thisValue, PropertyName)

Modified: trunk/Source/WebCore/bindings/scripts/test/TestObj.idl (206965 => 206966)


--- trunk/Source/WebCore/bindings/scripts/test/TestObj.idl	2016-10-09 04:17:26 UTC (rev 206965)
+++ trunk/Source/WebCore/bindings/scripts/test/TestObj.idl	2016-10-09 07:34:08 UTC (rev 206966)
@@ -386,6 +386,8 @@
     attribute _optional                attributeWithReservedEnumType;
     void _any(unrestricted float a, long b);
 
+
+    readonly attribute Promise testReadOnlyPromiseAttribute;
     // Promise function
     Promise testPromiseFunction();
     Promise testPromiseFunctionWithFloatArgument(float a);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to