Unable to sign in leetcode.
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Feb 2019 20:14:58 +0000 (20:14 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Feb 2019 20:14:58 +0000 (20:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194366
rdar://problem/47259025.

Reviewed by Chris Dumez.

Source/WebCore:

In case a signal is passed as part of a FetchRequestInit,
the IDL binding code is throwing an exception in case signal is not an AbortSignal object.
This breaks an AbortSignal shim used in some web sites.
Relaxed the IDL binding rule by marking signal as any and doing the conversion in FetchRequest.

Test: http/wpt/fetch/request-abort.html
Also covered by manually signing in to leetcode.

* Modules/fetch/FetchRequest.cpp:
(WebCore::FetchRequest::initializeWith):
* Modules/fetch/FetchRequestInit.h:
(WebCore::FetchRequestInit::hasMembers const):
* Modules/fetch/FetchRequestInit.idl:

LayoutTests:

* http/wpt/fetch/request-abort-expected.txt: Added.
* http/wpt/fetch/request-abort.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/http/wpt/fetch/request-abort-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/fetch/request-abort.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/fetch/FetchRequest.cpp
Source/WebCore/Modules/fetch/FetchRequestInit.h
Source/WebCore/Modules/fetch/FetchRequestInit.idl

index afd05f7..50b5855 100644 (file)
@@ -1,3 +1,14 @@
+2019-02-07  Youenn Fablet  <youenn@apple.com>
+
+        Unable to sign in leetcode.
+        https://bugs.webkit.org/show_bug.cgi?id=194366
+        rdar://problem/47259025.
+
+        Reviewed by Chris Dumez.
+
+        * http/wpt/fetch/request-abort-expected.txt: Added.
+        * http/wpt/fetch/request-abort.html: Added.
+
 2019-02-07  Alex Christensen  <achristensen@webkit.org>
 
         Deprecate WKBundlePageSetDefersLoading
diff --git a/LayoutTests/http/wpt/fetch/request-abort-expected.txt b/LayoutTests/http/wpt/fetch/request-abort-expected.txt
new file mode 100644 (file)
index 0000000..57cd5f3
--- /dev/null
@@ -0,0 +1,6 @@
+CONSOLE MESSAGE: line 14: FetchRequestInit.signal should be undefined, null or an AbortSignal object.
+CONSOLE MESSAGE: line 28: FetchRequestInit.signal should be undefined, null or an AbortSignal object.
+
+FAIL Request from URL with signal assert_throws: function "() => { new Request("/", {signal: "my signal"}) }" did not throw
+FAIL Request from request with signal assert_throws: function "() => { new Request(request, {signal: "my signal"}) }" did not throw
+
diff --git a/LayoutTests/http/wpt/fetch/request-abort.html b/LayoutTests/http/wpt/fetch/request-abort.html
new file mode 100644 (file)
index 0000000..5fcb1ec
--- /dev/null
@@ -0,0 +1,32 @@
+<!doctype html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <title>Request signal</title>
+        <script src="/resources/testharness.js"></script>
+        <script src="/resources/testharnessreport.js"></script>
+    </head>
+    <body>
+        <script>
+test(() => {
+    new Request("/", {signal: null});
+    new Request("/", {signal: undefined});
+    assert_throws(new TypeError, () => { new Request("/", {signal: "my signal"}) });
+}, "Request from URL with signal");
+
+test(() => {
+    const controller = new AbortController();
+    const request = new Request("/", {signal : controller.signal});
+    controller.abort();
+
+    const r1 = new Request(request, {signal: undefined});
+    assert_true(r1.signal.aborted, "r1 signal is aborted");
+
+    const r2 = new Request(request, {signal: null});
+    assert_false(r2.signal.aborted, "r2 signal is not aborted");
+
+    assert_throws(new TypeError, () => { new Request(request, {signal: "my signal"}) });
+}, "Request from request with signal");
+        </script>
+    </body>
+</html>
index 6922c00..f461c5a 100644 (file)
@@ -1,5 +1,27 @@
 2019-02-07  Youenn Fablet  <youenn@apple.com>
 
+        Unable to sign in leetcode.
+        https://bugs.webkit.org/show_bug.cgi?id=194366
+        rdar://problem/47259025.
+
+        Reviewed by Chris Dumez.
+
+        In case a signal is passed as part of a FetchRequestInit,
+        the IDL binding code is throwing an exception in case signal is not an AbortSignal object.
+        This breaks an AbortSignal shim used in some web sites.
+        Relaxed the IDL binding rule by marking signal as any and doing the conversion in FetchRequest.
+
+        Test: http/wpt/fetch/request-abort.html
+        Also covered by manually signing in to leetcode.
+
+        * Modules/fetch/FetchRequest.cpp:
+        (WebCore::FetchRequest::initializeWith):
+        * Modules/fetch/FetchRequestInit.h:
+        (WebCore::FetchRequestInit::hasMembers const):
+        * Modules/fetch/FetchRequestInit.idl:
+
+2019-02-07  Youenn Fablet  <youenn@apple.com>
+
         Make to clear sources from UserMediaCaptureManagerProxy and UserMediaCaptureManager when no longer needed
         https://bugs.webkit.org/show_bug.cgi?id=194312
 
index c0790bc..cfb9c4b 100644 (file)
@@ -30,6 +30,7 @@
 #include "FetchRequest.h"
 
 #include "HTTPParsers.h"
+#include "JSAbortSignal.h"
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
 
@@ -159,8 +160,14 @@ ExceptionOr<void> FetchRequest::initializeWith(const String& url, Init&& init)
     if (optionsResult.hasException())
         return optionsResult.releaseException();
 
-    if (init.signal && init.signal.value())
-        m_signal->follow(*init.signal.value());
+    if (init.signal) {
+        if (auto* signal = JSAbortSignal::toWrapped(scriptExecutionContext()->vm(), init.signal))
+            m_signal->follow(*signal);
+        else if (!init.signal.isUndefinedOrNull())  {
+            ASCIILiteral consoleMessage { "FetchRequestInit.signal should be undefined, null or an AbortSignal object."_s };
+            scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, consoleMessage);
+        }
+    }
 
     if (init.headers) {
         auto fillResult = m_headers->fill(*init.headers);
@@ -191,11 +198,16 @@ ExceptionOr<void> FetchRequest::initializeWith(FetchRequest& input, Init&& init)
     if (optionsResult.hasException())
         return optionsResult.releaseException();
 
-    if (init.signal) {
-        if (init.signal.value())
-            m_signal->follow(*init.signal.value());
+    if (init.signal && !init.signal.isUndefined()) {
+        if (auto* signal = JSAbortSignal::toWrapped(scriptExecutionContext()->vm(), init.signal))
+            m_signal->follow(*signal);
+        else if (!init.signal.isNull()) {
+            ASCIILiteral consoleMessage { "FetchRequestInit.signal should be undefined, null or an AbortSignal object."_s };
+            scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, consoleMessage);
+        }
+
     } else
-        m_signal->follow(input.m_signal);
+        m_signal->follow(input.m_signal.get());
 
     if (init.headers) {
         auto fillResult = m_headers->fill(*init.headers);
index a8d374b..c065e15 100644 (file)
@@ -47,10 +47,10 @@ struct FetchRequestInit {
     Optional<FetchOptions::Redirect> redirect;
     String integrity;
     Optional<bool> keepalive;
-    Optional<AbortSignal*> signal;
+    JSC::JSValue signal;
     JSC::JSValue window;
 
-    bool hasMembers() const { return !method.isEmpty() || headers || body || !referrer.isEmpty() || referrerPolicy || mode || credentials || cache || redirect || !integrity.isEmpty() || keepalive || !window.isUndefined() || signal; }
+    bool hasMembers() const { return !method.isEmpty() || headers || body || !referrer.isEmpty() || referrerPolicy || mode || credentials || cache || redirect || !integrity.isEmpty() || keepalive || !window.isUndefined() || !signal.isUndefined(); }
 };
 
 }
index cc7ca55..f2ed837 100644 (file)
@@ -39,6 +39,6 @@ dictionary FetchRequestInit {
     FetchRequestRedirect redirect;
     DOMString integrity;
     boolean keepalive;
-    AbortSignal? signal;
+    any signal;
     any window; // can only be set to null
 };