rel="noreferrer" should make window.opener null
authorap@apple.com <ap@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Feb 2015 18:16:00 +0000 (18:16 +0000)
committerap@apple.com <ap@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Feb 2015 18:16:00 +0000 (18:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=141579

Reviewed by Darin Adler.

Source/WebCore:

Tests: http/tests/navigation/target-blank-opener-post.html
       http/tests/navigation/target-blank-opener.html

We used to avoid passing window.opener policy by temporarily storing it in a FrameLoader
member variable. This works for some clients - ones that invoke delegate callbacks
synchronously - but not in the general case.

So, changed to passing the policy explicitly.

* WebCore.exp.in:
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::FrameLoader):
(WebCore::FrameLoader::urlSelected):
(WebCore::FrameLoader::loadURLIntoChildFrame):
(WebCore::FrameLoader::loadFrameRequest):
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::load):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
* loader/FrameLoader.h:
(WebCore::FrameLoader::suppressOpenerInNewFrame): Deleted.
* loader/FrameLoaderTypes.h:
* loader/NavigationScheduler.cpp:
* page/ContextMenuController.cpp:
(WebCore::openNewWindow):
(WebCore::ContextMenuController::contextMenuItemSelected):

Source/WebKit/ios:

* WebView/WebPDFViewPlaceholder.mm:
(-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]): Updated for a new WebCore
function signature. There is no rel="noreferrer" in PDF, so we can just always allow.

Source/WebKit/mac:

* WebView/WebPDFView.mm:
(-[WebPDFView PDFViewWillClickOnLink:withURL:]): Updated for a new WebCore
function signature. There is no rel="noreferrer" in PDF, so we can just always allow.

LayoutTests:

Unfortunately, these tests are not quite real, because they pass even without the
fix. There reason is that delegates respond synchronously in WKTR and DRT.

But if there is any large refactoring, there is a non-zero chance that the tests
will catch future mistakes.

* http/tests/navigation/resources/target-blank-opener-post-window.php: Added.
* http/tests/navigation/resources/target-blank-opener-window.php: Added.
* http/tests/navigation/target-blank-opener-expected.txt: Added.
* http/tests/navigation/target-blank-opener-post-expected.txt: Added.
* http/tests/navigation/target-blank-opener-post.html: Added.
* http/tests/navigation/target-blank-opener.html: Added.

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

18 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/navigation/resources/target-blank-opener-post-window.php [new file with mode: 0644]
LayoutTests/http/tests/navigation/resources/target-blank-opener-window.php [new file with mode: 0644]
LayoutTests/http/tests/navigation/target-blank-opener-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/navigation/target-blank-opener-post-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/navigation/target-blank-opener-post.html [new file with mode: 0644]
LayoutTests/http/tests/navigation/target-blank-opener.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Source/WebCore/loader/FrameLoaderTypes.h
Source/WebCore/loader/NavigationScheduler.cpp
Source/WebCore/page/ContextMenuController.cpp
Source/WebKit/ios/ChangeLog
Source/WebKit/ios/WebView/WebPDFViewPlaceholder.mm
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebPDFView.mm

index 80479c2..2c6aabc 100644 (file)
@@ -1,3 +1,23 @@
+2015-02-14  Alexey Proskuryakov  <ap@apple.com>
+
+        rel="noreferrer" should make window.opener null
+        https://bugs.webkit.org/show_bug.cgi?id=141579
+
+        Reviewed by Darin Adler.
+
+        Unfortunately, these tests are not quite real, because they pass even without the
+        fix. There reason is that delegates respond synchronously in WKTR and DRT.
+
+        But if there is any large refactoring, there is a non-zero chance that the tests
+        will catch future mistakes.
+
+        * http/tests/navigation/resources/target-blank-opener-post-window.php: Added.
+        * http/tests/navigation/resources/target-blank-opener-window.php: Added.
+        * http/tests/navigation/target-blank-opener-expected.txt: Added.
+        * http/tests/navigation/target-blank-opener-post-expected.txt: Added.
+        * http/tests/navigation/target-blank-opener-post.html: Added.
+        * http/tests/navigation/target-blank-opener.html: Added.
+
 2015-02-14  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Re-ordering expectations.
diff --git a/LayoutTests/http/tests/navigation/resources/target-blank-opener-post-window.php b/LayoutTests/http/tests/navigation/resources/target-blank-opener-post-window.php
new file mode 100644 (file)
index 0000000..a74de20
--- /dev/null
@@ -0,0 +1,10 @@
+<p>Referrer: <?php echo $_SERVER['HTTP_REFERER'] ?></p>
+<script>
+console.log("Referrer: <?php echo $_SERVER['HTTP_REFERER'] ?>");
+
+var result = "window.opener: " + (window.opener ? "PASS" : "FAIL");
+document.write(result);
+console.log(result);
+if (window.testRunner)
+    testRunner.notifyDone();
+</script>
diff --git a/LayoutTests/http/tests/navigation/resources/target-blank-opener-window.php b/LayoutTests/http/tests/navigation/resources/target-blank-opener-window.php
new file mode 100644 (file)
index 0000000..dcaaa86
--- /dev/null
@@ -0,0 +1,10 @@
+<p>Referrer: <?php echo $_SERVER['HTTP_REFERER'] ?></p>
+<script>
+console.log("Referrer: <?php echo $_SERVER['HTTP_REFERER'] ?>");
+
+var result = "window.opener: " + (window.opener ? "FAIL" : "PASS");
+document.write(result);
+console.log(result);
+if (window.testRunner)
+    testRunner.notifyDone();
+</script>
diff --git a/LayoutTests/http/tests/navigation/target-blank-opener-expected.txt b/LayoutTests/http/tests/navigation/target-blank-opener-expected.txt
new file mode 100644 (file)
index 0000000..8bdd2ec
--- /dev/null
@@ -0,0 +1,5 @@
+CONSOLE MESSAGE: line 3: Referrer: 
+CONSOLE MESSAGE: line 7: window.opener: PASS
+Test that a new window opened via <a target='_blank'> with rel="noreferrer" has a null opener.
+
+Click me to test.
diff --git a/LayoutTests/http/tests/navigation/target-blank-opener-post-expected.txt b/LayoutTests/http/tests/navigation/target-blank-opener-post-expected.txt
new file mode 100644 (file)
index 0000000..ba7dd67
--- /dev/null
@@ -0,0 +1,5 @@
+CONSOLE MESSAGE: line 3: Referrer: http://127.0.0.1:8000/navigation/target-blank-opener-post.html
+CONSOLE MESSAGE: line 7: window.opener: PASS
+Test that rel="noreferrer" is unsupported by form elements, and that window.opener is available when form submission opens a new window.
+
+
diff --git a/LayoutTests/http/tests/navigation/target-blank-opener-post.html b/LayoutTests/http/tests/navigation/target-blank-opener-post.html
new file mode 100644 (file)
index 0000000..88695bf
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<p>Test that rel="noreferrer" is unsupported by form elements, and that window.opener is available when form submission opens a new window.</p>
+<form id="testForm" action="resources/target-blank-opener-post-window.php" target="_blank" rel="noreferrer" method="post">
+<input type="submit" value="Test"></input>
+<form>
+<script>
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.setCanOpenWindows(true);
+}
+
+document.forms[0].submit();
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/navigation/target-blank-opener.html b/LayoutTests/http/tests/navigation/target-blank-opener.html
new file mode 100644 (file)
index 0000000..4377287
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<p>Test that a new window opened via &lt;a target='_blank'&gt; with rel="noreferrer" has a null opener.</p>
+<a id="testLink" href="resources/target-blank-opener-window.php" target="_blank" rel="noreferrer">Click me to test.</a>
+<script>
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.setCanOpenWindows(true);
+}
+
+document.getElementById("testLink").click();
+
+</script>
+</body>
+</html>
index 188e464..b33ffa5 100644 (file)
@@ -1,3 +1,37 @@
+2015-02-14  Alexey Proskuryakov  <ap@apple.com>
+
+        rel="noreferrer" should make window.opener null
+        https://bugs.webkit.org/show_bug.cgi?id=141579
+
+        Reviewed by Darin Adler.
+
+        Tests: http/tests/navigation/target-blank-opener-post.html
+               http/tests/navigation/target-blank-opener.html
+
+        We used to avoid passing window.opener policy by temporarily storing it in a FrameLoader
+        member variable. This works for some clients - ones that invoke delegate callbacks
+        synchronously - but not in the general case.
+
+        So, changed to passing the policy explicitly.
+
+        * WebCore.exp.in:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::FrameLoader):
+        (WebCore::FrameLoader::urlSelected):
+        (WebCore::FrameLoader::loadURLIntoChildFrame):
+        (WebCore::FrameLoader::loadFrameRequest):
+        (WebCore::FrameLoader::loadURL):
+        (WebCore::FrameLoader::load):
+        (WebCore::FrameLoader::loadPostRequest):
+        (WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
+        * loader/FrameLoader.h:
+        (WebCore::FrameLoader::suppressOpenerInNewFrame): Deleted.
+        * loader/FrameLoaderTypes.h:
+        * loader/NavigationScheduler.cpp:
+        * page/ContextMenuController.cpp:
+        (WebCore::openNewWindow):
+        (WebCore::ContextMenuController::contextMenuItemSelected):
+
 2015-02-14  David Kilzer  <ddkilzer@apple.com>
 
         REGRESSION (r180082): WebCore build on Mountain Lion fails due to weak export for i386
index d71fc1e..439c8d6 100644 (file)
@@ -150,7 +150,7 @@ __ZN7WebCore11FrameLoader11urlSelectedERKNS_3URLERKN3WTF6StringENS4_10PassRefPtr
 __ZN7WebCore11FrameLoader14detachChildrenEv
 __ZN7WebCore11FrameLoader14stopAllLoadersENS_26ClearProvisionalItemPolicyE
 __ZN7WebCore11FrameLoader16detachFromParentEv
-__ZN7WebCore11FrameLoader16loadFrameRequestERKNS_16FrameLoadRequestENS_11LockHistoryENS_19LockBackForwardListEN3WTF10PassRefPtrINS_5EventEEENS7_INS_9FormStateEEENS_18ShouldSendReferrerENS_27AllowNavigationToInvalidURLE
+__ZN7WebCore11FrameLoader16loadFrameRequestERKNS_16FrameLoadRequestENS_11LockHistoryENS_19LockBackForwardListEN3WTF10PassRefPtrINS_5EventEEENS7_INS_9FormStateEEENS_18ShouldSendReferrerENS_27AllowNavigationToInvalidURLENS_20NewFrameOpenerPolicyE
 __ZN7WebCore11FrameLoader17stopForUserCancelEb
 __ZN7WebCore11FrameLoader21loadURLIntoChildFrameERKNS_3URLERKN3WTF6StringEPNS_5FrameE
 __ZN7WebCore11FrameLoader22findFrameForNavigationERKN3WTF12AtomicStringEPNS_8DocumentE
index da76f62..05c8206 100644 (file)
@@ -235,7 +235,6 @@ FrameLoader::FrameLoader(Frame& frame, FrameLoaderClient& client)
     , m_shouldCallCheckLoadComplete(false)
     , m_opener(nullptr)
     , m_loadingFromCachedPage(false)
-    , m_suppressOpenerInNewFrame(false)
     , m_currentNavigationHasShownBeforeUnloadConfirmPanel(false)
     , m_loadsSynchronously(false)
     , m_forcedSandboxFlags(SandboxNone)
@@ -330,8 +329,6 @@ void FrameLoader::urlSelected(const URL& url, const String& passedTarget, PassRe
 // corresponding parameter from ScriptController::executeIfJavaScriptURL() is addressed.
 void FrameLoader::urlSelected(const FrameLoadRequest& passedRequest, PassRefPtr<Event> triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
 {
-    ASSERT(!m_suppressOpenerInNewFrame);
-
     Ref<Frame> protect(m_frame);
     FrameLoadRequest frameRequest(passedRequest);
 
@@ -341,13 +338,11 @@ void FrameLoader::urlSelected(const FrameLoadRequest& passedRequest, PassRefPtr<
     if (frameRequest.frameName().isEmpty())
         frameRequest.setFrameName(m_frame.document()->baseTarget());
 
-    if (shouldSendReferrer == NeverSendReferrer)
-        m_suppressOpenerInNewFrame = true;
     addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin());
 
-    loadFrameRequest(frameRequest, lockHistory, lockBackForwardList, triggeringEvent, 0, shouldSendReferrer, allowNavigationToInvalidURL);
+    NewFrameOpenerPolicy openerPolicy = (shouldSendReferrer == NeverSendReferrer) ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow;
 
-    m_suppressOpenerInNewFrame = false;
+    loadFrameRequest(frameRequest, lockHistory, lockBackForwardList, triggeringEvent, 0, shouldSendReferrer, allowNavigationToInvalidURL, openerPolicy);
 }
 
 void FrameLoader::submitForm(PassRefPtr<FormSubmission> submission)
@@ -925,7 +920,7 @@ void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, F
         }
     }
 
-    childFrame->loader().loadURL(url, referer, "_self", LockHistory::No, FrameLoadType::RedirectWithLockedBackForwardList, 0, 0, AllowNavigationToInvalidURL::Yes);
+    childFrame->loader().loadURL(url, referer, "_self", LockHistory::No, FrameLoadType::RedirectWithLockedBackForwardList, 0, 0, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
 }
 
 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
@@ -1150,7 +1145,7 @@ void FrameLoader::setupForReplace()
 }
 
 void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, LockHistory lockHistory, LockBackForwardList lockBackForwardList,
-    PassRefPtr<Event> event, PassRefPtr<FormState> formState, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
+    PassRefPtr<Event> event, PassRefPtr<FormState> formState, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy openerPolicy)
 {    
     // Protect frame from getting blown away inside dispatchBeforeLoadEvent in loadWithDocumentLoader.
     Ref<Frame> protect(m_frame);
@@ -1180,9 +1175,9 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, LockHistory
         loadType = FrameLoadType::Standard;
 
     if (request.resourceRequest().httpMethod() == "POST")
-        loadPostRequest(request.resourceRequest(), referrer, request.frameName(), lockHistory, loadType, event, formState.get(), allowNavigationToInvalidURL);
+        loadPostRequest(request.resourceRequest(), referrer, request.frameName(), lockHistory, loadType, event, formState.get(), allowNavigationToInvalidURL, openerPolicy);
     else
-        loadURL(request.resourceRequest().url(), referrer, request.frameName(), lockHistory, loadType, event, formState.get(), allowNavigationToInvalidURL);
+        loadURL(request.resourceRequest().url(), referrer, request.frameName(), lockHistory, loadType, event, formState.get(), allowNavigationToInvalidURL, openerPolicy);
 
     // FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual
     // load if frame names have changed.
@@ -1197,7 +1192,7 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, LockHistory
 }
 
 void FrameLoader::loadURL(const URL& newURL, const String& referrer, const String& frameName, LockHistory lockHistory, FrameLoadType newLoadType,
-    PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
+    PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy openerPolicy)
 {
     if (m_inStopAllLoaders)
         return;
@@ -1226,7 +1221,7 @@ void FrameLoader::loadURL(const URL& newURL, const String& referrer, const Strin
     // The search for a target frame is done earlier in the case of form submission.
     Frame* targetFrame = isFormSubmission ? 0 : findFrameForNavigation(frameName);
     if (targetFrame && targetFrame != &m_frame) {
-        targetFrame->loader().loadURL(newURL, referrer, "_self", lockHistory, newLoadType, event, formState.release(), allowNavigationToInvalidURL);
+        targetFrame->loader().loadURL(newURL, referrer, "_self", lockHistory, newLoadType, event, formState.release(), allowNavigationToInvalidURL, openerPolicy);
         return;
     }
 
@@ -1236,8 +1231,8 @@ void FrameLoader::loadURL(const URL& newURL, const String& referrer, const Strin
     NavigationAction action(request, newLoadType, isFormSubmission, event);
 
     if (!targetFrame && !frameName.isEmpty()) {
-        policyChecker().checkNewWindowPolicy(action, request, formState.release(), frameName, [this, allowNavigationToInvalidURL](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
-            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL);
+        policyChecker().checkNewWindowPolicy(action, request, formState.release(), frameName, [this, allowNavigationToInvalidURL, openerPolicy](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
+            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
         });
         return;
     }
@@ -1306,7 +1301,7 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
 
     if (request.shouldCheckNewWindowPolicy()) {
         policyChecker().checkNewWindowPolicy(NavigationAction(request.resourceRequest(), NavigationTypeOther), request.resourceRequest(), nullptr, request.frameName(), [this](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
-            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes);
+            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
         });
 
         return;
@@ -2612,7 +2607,7 @@ void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const String&
     request.setHTTPOrigin(origin);
 }
 
-void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String& referrer, const String& frameName, LockHistory lockHistory, FrameLoadType loadType, PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
+void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String& referrer, const String& frameName, LockHistory lockHistory, FrameLoadType loadType, PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy openerPolicy)
 {
     RefPtr<FormState> formState = prpFormState;
 
@@ -2644,8 +2639,8 @@ void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String
             return;
         }
 
-        policyChecker().checkNewWindowPolicy(action, workingResourceRequest, formState.release(), frameName, [this, allowNavigationToInvalidURL](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
-            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL);
+        policyChecker().checkNewWindowPolicy(action, workingResourceRequest, formState.release(), frameName, [this, allowNavigationToInvalidURL, openerPolicy](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
+            continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
         });
         return;
     }
@@ -2962,7 +2957,7 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest& reque
 }
 
 void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& request,
-    PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
+    PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy openerPolicy)
 {
     if (!shouldContinue)
         return;
@@ -2977,7 +2972,7 @@ void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& reques
 
     mainFrame->page()->setOpenedByDOM();
     mainFrame->loader().m_client.dispatchShow();
-    if (!m_suppressOpenerInNewFrame) {
+    if (openerPolicy == NewFrameOpenerPolicy::Allow) {
         mainFrame->loader().setOpener(frame.ptr());
         mainFrame->document()->setReferrerPolicy(frame->document()->referrerPolicy());
     }
index 619c7c4..633407e 100644 (file)
@@ -107,7 +107,7 @@ public:
     // FIXME: These are all functions which start loads. We have too many.
     WEBCORE_EXPORT void loadURLIntoChildFrame(const URL&, const String& referer, Frame*);
     WEBCORE_EXPORT void loadFrameRequest(const FrameLoadRequest&, LockHistory, LockBackForwardList, // Called by submitForm, calls loadPostRequest and loadURL.
-        PassRefPtr<Event>, PassRefPtr<FormState>, ShouldSendReferrer, AllowNavigationToInvalidURL);
+        PassRefPtr<Event>, PassRefPtr<FormState>, ShouldSendReferrer, AllowNavigationToInvalidURL, NewFrameOpenerPolicy);
 
     WEBCORE_EXPORT void load(const FrameLoadRequest&);
 
@@ -265,8 +265,6 @@ public:
 
     WEBCORE_EXPORT void setOriginalURLForDownloadRequest(ResourceRequest&);
 
-    bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; }
-
     bool quickRedirectComing() const { return m_quickRedirectComing; }
 
     WEBCORE_EXPORT bool shouldClose();
@@ -318,7 +316,7 @@ private:
     bool handleBeforeUnloadEvent(Chrome&, FrameLoader* frameLoaderBeingNavigated);
 
     void continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState>, bool shouldContinue, AllowNavigationToInvalidURL);
-    void continueLoadAfterNewWindowPolicy(const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue, AllowNavigationToInvalidURL);
+    void continueLoadAfterNewWindowPolicy(const ResourceRequest&, PassRefPtr<FormState>, const String& frameName, const NavigationAction&, bool shouldContinue, AllowNavigationToInvalidURL, NewFrameOpenerPolicy);
     void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
 
     bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const URL&);
@@ -348,9 +346,9 @@ private:
         LockHistory, FrameLoadType, PassRefPtr<FormState>, AllowNavigationToInvalidURL);
 
     void loadPostRequest(const ResourceRequest&, const String& referrer,                // Called by loadFrameRequest, calls loadWithNavigationAction
-        const String& frameName, LockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>, AllowNavigationToInvalidURL);
+        const String& frameName, LockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>, AllowNavigationToInvalidURL, NewFrameOpenerPolicy);
     void loadURL(const URL&, const String& referrer, const String& frameName,          // Called by loadFrameRequest, calls loadWithNavigationAction or dispatches to navigation policy delegate
-        LockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>, AllowNavigationToInvalidURL);
+        LockHistory, FrameLoadType, PassRefPtr<Event>, PassRefPtr<FormState>, AllowNavigationToInvalidURL, NewFrameOpenerPolicy);
 
     bool shouldReload(const URL& currentURL, const URL& destinationURL);
 
@@ -429,7 +427,6 @@ private:
     HashSet<Frame*> m_openedFrames;
 
     bool m_loadingFromCachedPage;
-    bool m_suppressOpenerInNewFrame;
 
     bool m_currentNavigationHasShownBeforeUnloadConfirmPanel;
 
index 9956d1a..e020c93 100644 (file)
@@ -57,6 +57,11 @@ enum class FrameLoadType {
     ReloadFromOrigin,
 };
 
+enum class NewFrameOpenerPolicy {
+    Suppress,
+    Allow
+};
+
     enum NavigationType {
         NavigationTypeLinkClicked,
         NavigationTypeFormSubmitted,
index 91cba06..3af28db 100644 (file)
@@ -246,7 +246,7 @@ public:
             return;
         FrameLoadRequest frameRequest(requestingDocument->securityOrigin());
         m_submission->populateFrameLoadRequest(frameRequest);
-        frame.loader().loadFrameRequest(frameRequest, lockHistory(), lockBackForwardList(), m_submission->event(), m_submission->state(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes);
+        frame.loader().loadFrameRequest(frameRequest, lockHistory(), lockBackForwardList(), m_submission->event(), m_submission->state(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
     }
     
     virtual void didStartTimer(Frame& frame, Timer& timer) override
index 9224eee..13c156a 100644 (file)
@@ -202,7 +202,7 @@ static void openNewWindow(const URL& urlToLoad, Frame* frame)
     if (!newPage)
         return;
     newPage->chrome().show();
-    newPage->mainFrame().loader().loadFrameRequest(request, LockHistory::No, LockBackForwardList::No, 0, 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes);
+    newPage->mainFrame().loader().loadFrameRequest(request, LockHistory::No, LockBackForwardList::No, 0, 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
 }
 
 #if PLATFORM(GTK)
@@ -401,12 +401,12 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
         break;
     case ContextMenuItemTagOpenLink:
         if (Frame* targetFrame = m_context.hitTestResult().targetFrame())
-            targetFrame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer())), LockHistory::No, LockBackForwardList::No, 0, 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes);
+            targetFrame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer())), LockHistory::No, LockBackForwardList::No, 0, 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
         else
             openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame);
         break;
     case ContextMenuItemTagOpenLinkInThisWindow:
-        frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer())), LockHistory::No, LockBackForwardList::No, 0, 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes);
+        frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer())), LockHistory::No, LockBackForwardList::No, 0, 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
         break;
     case ContextMenuItemTagBold:
         frame->editor().command("ToggleBold").execute();
index 3ef5f16..2ed2d6f 100644 (file)
@@ -1,3 +1,14 @@
+2015-02-14  Alexey Proskuryakov  <ap@apple.com>
+
+        rel="noreferrer" should make window.opener null
+        https://bugs.webkit.org/show_bug.cgi?id=141579
+
+        Reviewed by Darin Adler.
+
+        * WebView/WebPDFViewPlaceholder.mm:
+        (-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]): Updated for a new WebCore
+        function signature. There is no rel="noreferrer" in PDF, so we can just always allow.
+
 2015-02-03  Enrica Casucci  <enrica@apple.com>
 
         [iOS] Add support for deleteFromInputWithFlags.
index 298ef5b..2f468d0 100644 (file)
@@ -475,7 +475,7 @@ static const float PAGE_HEIGHT_INSET = 4.0f * 2.0f;
 
     // Call to the frame loader because this is where our security checks are made.
     Frame* frame = core([_dataSource webFrame]);
-    frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(URL)), LockHistory::No, LockBackForwardList::No, event.get(), 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes);
+    frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(URL)), LockHistory::No, LockBackForwardList::No, event.get(), 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
 }
 
 @end
index b8a266c..045acab 100644 (file)
@@ -1,3 +1,14 @@
+2015-02-14  Alexey Proskuryakov  <ap@apple.com>
+
+        rel="noreferrer" should make window.opener null
+        https://bugs.webkit.org/show_bug.cgi?id=141579
+
+        Reviewed by Darin Adler.
+
+        * WebView/WebPDFView.mm:
+        (-[WebPDFView PDFViewWillClickOnLink:withURL:]): Updated for a new WebCore
+        function signature. There is no rel="noreferrer" in PDF, so we can just always allow.
+
 2015-02-05  Youenn Fablet  <youenn.fablet@crf.canon.fr> and Xabier Rodriguez Calvar <calvaris@igalia.com>
 
         [Streams API] Implement a barebone ReadableStream interface
index 762959b..bd385ad 100644 (file)
@@ -1032,7 +1032,7 @@ static BOOL isFrameInRange(WebFrame *frame, DOMRange *range)
 
     // Call to the frame loader because this is where our security checks are made.
     Frame* frame = core([dataSource webFrame]);
-    frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(URL)), LockHistory::No, LockBackForwardList::No, event.get(), 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes);
+    frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(URL)), LockHistory::No, LockBackForwardList::No, event.get(), 0, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow);
 }
 
 - (void)PDFViewOpenPDFInNativeApplication:(PDFView *)sender