Title: [255015] branches/safari-609-branch
Revision
255015
Author
[email protected]
Date
2020-01-23 13:43:50 -0800 (Thu, 23 Jan 2020)

Log Message

Cherry-pick r254652. rdar://problem/58811422

    Regression(r253213) Load hang and high CPU usage when trying to load myuhc.com
    https://bugs.webkit.org/show_bug.cgi?id=206315
    <rdar://problem/58139842>

    Reviewed by Geoffrey Garen.

    Source/WebCore:

    Starting in r253213, we now throw when trying to do a sync XHR during unload. Unfortunately, this is confusing the script
    on myuhc.com and it ends up retrying the sync XHR in a tight loop. To address the issue, I am putting in a safety net which
    ignores calls to XMLHttpRequest.send() instead of throwing, once we've reached 5 sync XHR failures during unload.

    Throwing is useful because this gives a change for Web authors to fall back to using Beacon API or Fetch KeepAlive if the
    sync XHR fails. There is already code out there doing just that. You could imagine content doing more than one sync XHR
    during unload, each one with a good beacon API fallback. For this reason, I put in a limit of 5 sync failures before
    we stop throwing. Having a limit is important to break bad loops when the content simply retries the same sync XHR load
    when the sync XHR send() call throws.

    Tests: fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html
           fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html

    * dom/Document.cpp:
    (WebCore::Document::didRejectSyncXHRDuringPageDismissal):
    (WebCore::Document::shouldIgnoreSyncXHRs const):
    * dom/Document.h:
    * loader/DocumentThreadableLoader.cpp:
    (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
    * xml/XMLHttpRequest.cpp:
    (WebCore::XMLHttpRequest::prepareToSend):

    LayoutTests:

    Add layout test coverage.

    * fast/xmlhttprequest/resources/xmlhttprequest-multiple-sync-xhr-during-unload-iframe.html: Added.
    * fast/xmlhttprequest/resources/xmlhttprequest-sync-xhr-failure-loop-during-unload-iframe.html: Added.
    * fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload-expected.txt: Added.
    * fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html: Added.
    * fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload-expected.txt: Added.
    * fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html: Added.

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-609-branch/LayoutTests/ChangeLog (255014 => 255015)


--- branches/safari-609-branch/LayoutTests/ChangeLog	2020-01-23 21:43:45 UTC (rev 255014)
+++ branches/safari-609-branch/LayoutTests/ChangeLog	2020-01-23 21:43:50 UTC (rev 255015)
@@ -1,5 +1,70 @@
 2020-01-23  Russell Epstein  <[email protected]>
 
+        Cherry-pick r254652. rdar://problem/58811422
+
+    Regression(r253213) Load hang and high CPU usage when trying to load myuhc.com
+    https://bugs.webkit.org/show_bug.cgi?id=206315
+    <rdar://problem/58139842>
+    
+    Reviewed by Geoffrey Garen.
+    
+    Source/WebCore:
+    
+    Starting in r253213, we now throw when trying to do a sync XHR during unload. Unfortunately, this is confusing the script
+    on myuhc.com and it ends up retrying the sync XHR in a tight loop. To address the issue, I am putting in a safety net which
+    ignores calls to XMLHttpRequest.send() instead of throwing, once we've reached 5 sync XHR failures during unload.
+    
+    Throwing is useful because this gives a change for Web authors to fall back to using Beacon API or Fetch KeepAlive if the
+    sync XHR fails. There is already code out there doing just that. You could imagine content doing more than one sync XHR
+    during unload, each one with a good beacon API fallback. For this reason, I put in a limit of 5 sync failures before
+    we stop throwing. Having a limit is important to break bad loops when the content simply retries the same sync XHR load
+    when the sync XHR send() call throws.
+    
+    Tests: fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html
+           fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html
+    
+    * dom/Document.cpp:
+    (WebCore::Document::didRejectSyncXHRDuringPageDismissal):
+    (WebCore::Document::shouldIgnoreSyncXHRs const):
+    * dom/Document.h:
+    * loader/DocumentThreadableLoader.cpp:
+    (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
+    * xml/XMLHttpRequest.cpp:
+    (WebCore::XMLHttpRequest::prepareToSend):
+    
+    LayoutTests:
+    
+    Add layout test coverage.
+    
+    * fast/xmlhttprequest/resources/xmlhttprequest-multiple-sync-xhr-during-unload-iframe.html: Added.
+    * fast/xmlhttprequest/resources/xmlhttprequest-sync-xhr-failure-loop-during-unload-iframe.html: Added.
+    * fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload-expected.txt: Added.
+    * fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html: Added.
+    * fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload-expected.txt: Added.
+    * fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@254652 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-01-15  Chris Dumez  <[email protected]>
+
+            Regression(r253213) Load hang and high CPU usage when trying to load myuhc.com
+            https://bugs.webkit.org/show_bug.cgi?id=206315
+            <rdar://problem/58139842>
+
+            Reviewed by Geoffrey Garen.
+
+            Add layout test coverage.
+
+            * fast/xmlhttprequest/resources/xmlhttprequest-multiple-sync-xhr-during-unload-iframe.html: Added.
+            * fast/xmlhttprequest/resources/xmlhttprequest-sync-xhr-failure-loop-during-unload-iframe.html: Added.
+            * fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload-expected.txt: Added.
+            * fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html: Added.
+            * fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload-expected.txt: Added.
+            * fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html: Added.
+
+2020-01-23  Russell Epstein  <[email protected]>
+
         Cherry-pick r254541. rdar://problem/58605951
 
     Supported mime types for encoding should be supported mime types for loading

Added: branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-multiple-sync-xhr-during-unload-iframe.html (0 => 255015)


--- branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-multiple-sync-xhr-during-unload-iframe.html	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-multiple-sync-xhr-during-unload-iframe.html	2020-01-23 21:43:50 UTC (rev 255015)
@@ -0,0 +1,22 @@
+<script>
+let xhrExceptionCount = 0;
+
+function doSyncXHR(i)
+{
+    try {
+        var xhr = new XMLHttpRequest();
+        xhr.open("GET", "xmlhttprequest-responsetype-json.json?" + i, false);
+        xhr.send(null);
+    } catch(e) {
+        xhrExceptionCount++;
+        return false;
+    }
+    return true;
+}
+
+_onunload_ = () => {
+    for (let i = 0; i < 5; i++)
+        doSyncXHR(i);
+    top.frameDidUnload(xhrExceptionCount);
+}
+</script>

Added: branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-sync-xhr-failure-loop-during-unload-iframe.html (0 => 255015)


--- branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-sync-xhr-failure-loop-during-unload-iframe.html	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/resources/xmlhttprequest-sync-xhr-failure-loop-during-unload-iframe.html	2020-01-23 21:43:50 UTC (rev 255015)
@@ -0,0 +1,18 @@
+<script>
+function doSyncXHR()
+{
+    try {
+        var xhr = new XMLHttpRequest();
+        xhr.open("GET", "xmlhttprequest-responsetype-json.json", false);
+        xhr.send(null);
+    } catch(e) {
+        return false;
+    }
+    return true;
+}
+
+_onunload_ = () => {
+    while (!doSyncXHR()) { };
+    top.frameDidUnload();
+}
+</script>

Added: branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload-expected.txt (0 => 255015)


--- branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload-expected.txt	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload-expected.txt	2020-01-23 21:43:50 UTC (rev 255015)
@@ -0,0 +1,16 @@
+frame "<!--frame1-->" - has 1 onunload handler(s)
+CONSOLE MESSAGE: line 9: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json?0.
+CONSOLE MESSAGE: line 9: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json?1.
+CONSOLE MESSAGE: line 9: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json?2.
+CONSOLE MESSAGE: line 9: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json?3.
+CONSOLE MESSAGE: line 9: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json?4.
+Makes sure that we throw when doing sync XHRs during unload.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS xhrExceptionCount is 5
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html (0 => 255015)


--- branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html	2020-01-23 21:43:50 UTC (rev 255015)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<iframe id="testFrame" src=""
+<script>
+description("Makes sure that we throw when doing sync XHRs during unload.");
+jsTestIsAsync = true;
+
+frameDidUnload = (_xhrExceptionCount) => {
+    xhrExceptionCount = _xhrExceptionCount;
+    shouldBe("xhrExceptionCount", "5");
+    finishJSTest();
+}
+
+_onload_ = () => {
+    testFrame.remove();
+}
+</script>
+</html>

Added: branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload-expected.txt (0 => 255015)


--- branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload-expected.txt	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload-expected.txt	2020-01-23 21:43:50 UTC (rev 255015)
@@ -0,0 +1,18 @@
+frame "<!--frame1-->" - has 1 onunload handler(s)
+CONSOLE MESSAGE: line 7: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json.
+CONSOLE MESSAGE: line 7: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json.
+CONSOLE MESSAGE: line 7: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json.
+CONSOLE MESSAGE: line 7: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json.
+CONSOLE MESSAGE: line 7: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json.
+CONSOLE MESSAGE: line 7: XMLHttpRequest cannot load xmlhttprequest-responsetype-json.json.
+CONSOLE MESSAGE: line 7: Ignoring XMLHttpRequest.send() call for 'xmlhttprequest-responsetype-json.json' because the maximum number of synchronous failures was reached.
+Makes sure that retrying failed sync XHRs in a loop during unload does not cause a hang.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS No hang while unloading the iframe
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html (0 => 255015)


--- branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html	                        (rev 0)
+++ branches/safari-609-branch/LayoutTests/fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html	2020-01-23 21:43:50 UTC (rev 255015)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<iframe id="testFrame" src=""
+<script>
+description("Makes sure that retrying failed sync XHRs in a loop during unload does not cause a hang.");
+jsTestIsAsync = true;
+
+frameDidUnload = () => {
+    testPassed("No hang while unloading the iframe");
+    finishJSTest();
+}
+
+_onload_ = () => {
+    testFrame.remove();
+}
+</script>
+</html>

Modified: branches/safari-609-branch/Source/WebCore/ChangeLog (255014 => 255015)


--- branches/safari-609-branch/Source/WebCore/ChangeLog	2020-01-23 21:43:45 UTC (rev 255014)
+++ branches/safari-609-branch/Source/WebCore/ChangeLog	2020-01-23 21:43:50 UTC (rev 255015)
@@ -1,5 +1,83 @@
 2020-01-23  Russell Epstein  <[email protected]>
 
+        Cherry-pick r254652. rdar://problem/58811422
+
+    Regression(r253213) Load hang and high CPU usage when trying to load myuhc.com
+    https://bugs.webkit.org/show_bug.cgi?id=206315
+    <rdar://problem/58139842>
+    
+    Reviewed by Geoffrey Garen.
+    
+    Source/WebCore:
+    
+    Starting in r253213, we now throw when trying to do a sync XHR during unload. Unfortunately, this is confusing the script
+    on myuhc.com and it ends up retrying the sync XHR in a tight loop. To address the issue, I am putting in a safety net which
+    ignores calls to XMLHttpRequest.send() instead of throwing, once we've reached 5 sync XHR failures during unload.
+    
+    Throwing is useful because this gives a change for Web authors to fall back to using Beacon API or Fetch KeepAlive if the
+    sync XHR fails. There is already code out there doing just that. You could imagine content doing more than one sync XHR
+    during unload, each one with a good beacon API fallback. For this reason, I put in a limit of 5 sync failures before
+    we stop throwing. Having a limit is important to break bad loops when the content simply retries the same sync XHR load
+    when the sync XHR send() call throws.
+    
+    Tests: fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html
+           fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html
+    
+    * dom/Document.cpp:
+    (WebCore::Document::didRejectSyncXHRDuringPageDismissal):
+    (WebCore::Document::shouldIgnoreSyncXHRs const):
+    * dom/Document.h:
+    * loader/DocumentThreadableLoader.cpp:
+    (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
+    * xml/XMLHttpRequest.cpp:
+    (WebCore::XMLHttpRequest::prepareToSend):
+    
+    LayoutTests:
+    
+    Add layout test coverage.
+    
+    * fast/xmlhttprequest/resources/xmlhttprequest-multiple-sync-xhr-during-unload-iframe.html: Added.
+    * fast/xmlhttprequest/resources/xmlhttprequest-sync-xhr-failure-loop-during-unload-iframe.html: Added.
+    * fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload-expected.txt: Added.
+    * fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html: Added.
+    * fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload-expected.txt: Added.
+    * fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html: Added.
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@254652 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-01-15  Chris Dumez  <[email protected]>
+
+            Regression(r253213) Load hang and high CPU usage when trying to load myuhc.com
+            https://bugs.webkit.org/show_bug.cgi?id=206315
+            <rdar://problem/58139842>
+
+            Reviewed by Geoffrey Garen.
+
+            Starting in r253213, we now throw when trying to do a sync XHR during unload. Unfortunately, this is confusing the script
+            on myuhc.com and it ends up retrying the sync XHR in a tight loop. To address the issue, I am putting in a safety net which
+            ignores calls to XMLHttpRequest.send() instead of throwing, once we've reached 5 sync XHR failures during unload.
+
+            Throwing is useful because this gives a change for Web authors to fall back to using Beacon API or Fetch KeepAlive if the
+            sync XHR fails. There is already code out there doing just that. You could imagine content doing more than one sync XHR
+            during unload, each one with a good beacon API fallback. For this reason, I put in a limit of 5 sync failures before
+            we stop throwing. Having a limit is important to break bad loops when the content simply retries the same sync XHR load
+            when the sync XHR send() call throws.
+
+            Tests: fast/xmlhttprequest/xmlhttprequest-multiple-sync-xhr-during-unload.html
+                   fast/xmlhttprequest/xmlhttprequest-sync-xhr-failure-loop-during-unload.html
+
+            * dom/Document.cpp:
+            (WebCore::Document::didRejectSyncXHRDuringPageDismissal):
+            (WebCore::Document::shouldIgnoreSyncXHRs const):
+            * dom/Document.h:
+            * loader/DocumentThreadableLoader.cpp:
+            (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
+            * xml/XMLHttpRequest.cpp:
+            (WebCore::XMLHttpRequest::prepareToSend):
+
+2020-01-23  Russell Epstein  <[email protected]>
+
         Cherry-pick r254541. rdar://problem/58605951
 
     Supported mime types for encoding should be supported mime types for loading

Modified: branches/safari-609-branch/Source/WebCore/dom/Document.cpp (255014 => 255015)


--- branches/safari-609-branch/Source/WebCore/dom/Document.cpp	2020-01-23 21:43:45 UTC (rev 255014)
+++ branches/safari-609-branch/Source/WebCore/dom/Document.cpp	2020-01-23 21:43:50 UTC (rev 255015)
@@ -8352,6 +8352,24 @@
         top.setHasEvaluatedUserAgentScripts();
 }
 
+void Document::didRejectSyncXHRDuringPageDismissal()
+{
+    ++m_numberOfRejectedSyncXHRs;
+    if (m_numberOfRejectedSyncXHRs > 1)
+        return;
+
+    postTask([this, weakThis = makeWeakPtr(*this)](auto&) mutable {
+        if (weakThis)
+            m_numberOfRejectedSyncXHRs = 0;
+    });
+}
+
+bool Document::shouldIgnoreSyncXHRs() const
+{
+    const unsigned maxRejectedSyncXHRsPerEventLoopIteration = 5;
+    return m_numberOfRejectedSyncXHRs > maxRejectedSyncXHRsPerEventLoopIteration;
+}
+
 #if ENABLE(APPLE_PAY)
 
 bool Document::isApplePayActive() const

Modified: branches/safari-609-branch/Source/WebCore/dom/Document.h (255014 => 255015)


--- branches/safari-609-branch/Source/WebCore/dom/Document.h	2020-01-23 21:43:45 UTC (rev 255014)
+++ branches/safari-609-branch/Source/WebCore/dom/Document.h	2020-01-23 21:43:50 UTC (rev 255015)
@@ -762,6 +762,9 @@
     void setFocusNavigationStartingNode(Node*);
     Element* focusNavigationStartingNode(FocusDirection) const;
 
+    void didRejectSyncXHRDuringPageDismissal();
+    bool shouldIgnoreSyncXHRs() const;
+
     enum class NodeRemoval { Node, ChildrenOfNode };
     void adjustFocusedNodeOnNodeRemoval(Node&, NodeRemoval = NodeRemoval::Node);
     void adjustFocusNavigationNodeOnNodeRemoval(Node&, NodeRemoval = NodeRemoval::Node);
@@ -2055,7 +2058,7 @@
     RefPtr<Worklet> m_paintWorklet;
     HashMap<String, Ref<PaintWorkletGlobalScope>> m_paintWorkletGlobalScopes;
 #endif
-
+    unsigned m_numberOfRejectedSyncXHRs { 0 };
     bool m_hasEvaluatedUserAgentScripts { false };
     bool m_isRunningUserScripts { false };
     bool m_mayBeDetachedFromFrame { true };

Modified: branches/safari-609-branch/Source/WebCore/loader/DocumentThreadableLoader.cpp (255014 => 255015)


--- branches/safari-609-branch/Source/WebCore/loader/DocumentThreadableLoader.cpp	2020-01-23 21:43:45 UTC (rev 255014)
+++ branches/safari-609-branch/Source/WebCore/loader/DocumentThreadableLoader.cpp	2020-01-23 21:43:50 UTC (rev 255015)
@@ -133,6 +133,7 @@
     ASSERT(m_async || m_referrer.isEmpty());
 
     if (document.settings().disallowSyncXHRDuringPageDismissalEnabled() && !m_async && (!document.page() || !document.page()->areSynchronousLoadsAllowed())) {
+        document.didRejectSyncXHRDuringPageDismissal();
         logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, request.url(), "Synchronous loads are not allowed at this time"));
         return;
     }

Modified: branches/safari-609-branch/Source/WebCore/xml/XMLHttpRequest.cpp (255014 => 255015)


--- branches/safari-609-branch/Source/WebCore/xml/XMLHttpRequest.cpp	2020-01-23 21:43:45 UTC (rev 255014)
+++ branches/safari-609-branch/Source/WebCore/xml/XMLHttpRequest.cpp	2020-01-23 21:43:50 UTC (rev 255015)
@@ -413,6 +413,11 @@
 
     auto& context = *scriptExecutionContext();
 
+    if (is<Document>(context) && downcast<Document>(context).shouldIgnoreSyncXHRs()) {
+        logConsoleError(scriptExecutionContext(), makeString("Ignoring XMLHttpRequest.send() call for '", m_url.string(), "' because the maximum number of synchronous failures was reached."));
+        return ExceptionOr<void> { };
+    }
+
     if (readyState() != OPENED || m_sendFlag)
         return ExceptionOr<void> { Exception { InvalidStateError } };
     ASSERT(!m_loader);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to