Link clicks in PDFs shouldn't send referrer headers.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Apr 2019 22:47:07 +0000 (22:47 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Apr 2019 22:47:07 +0000 (22:47 +0000)
<rdar://problem/21142581> and https://bugs.webkit.org/show_bug.cgi?id=196980

Reviewed by Tim Horton.

Source/WebKit:

* WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::clickedLink):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::navigateToPDFLinkWithSimulatedClick):

Source/WebKitLegacy/ios:

* WebView/WebPDFViewPlaceholder.mm:
(-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]):

Source/WebKitLegacy/mac:

* WebView/WebPDFView.mm:
(-[WebPDFView PDFViewWillClickOnLink:withURL:]):

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/PDFLinkReferrer.mm: Added.
(putPDFBytesCallback):
(emptyReleaseInfoCallback):
(createPDFWithLinkToURL):
(TEST):

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

Source/WebKit/ChangeLog
Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKitLegacy/ios/ChangeLog
Source/WebKitLegacy/ios/WebView/WebPDFViewPlaceholder.mm
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebPDFView.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/PDFLinkReferrer.mm [new file with mode: 0644]

index 5aa201f..46fa99a 100644 (file)
@@ -1,3 +1,15 @@
+2019-04-17  Brady Eidson  <beidson@apple.com>
+
+        Link clicks in PDFs shouldn't send referrer headers.
+        <rdar://problem/21142581> and https://bugs.webkit.org/show_bug.cgi?id=196980
+
+        Reviewed by Tim Horton.
+
+        * WebProcess/Plugins/PDF/PDFPlugin.mm:
+        (WebKit::PDFPlugin::clickedLink):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::navigateToPDFLinkWithSimulatedClick):
+
 2019-04-17  Andy Estes  <aestes@apple.com>
 
         [iOS] Support multiple file selection in UIDocumentPickerViewController
index 8dee71e..1588bd0 100644 (file)
@@ -1732,7 +1732,7 @@ void PDFPlugin::clickedLink(NSURL *url)
     if (m_lastMouseEvent.type() != WebEvent::NoType)
         coreEvent = MouseEvent::create(eventNames().clickEvent, &frame->windowProxy(), platform(m_lastMouseEvent), 0, 0);
 
-    frame->loader().urlSelected(coreURL, emptyString(), coreEvent.get(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldAllow);
+    frame->loader().urlSelected(coreURL, emptyString(), coreEvent.get(), LockHistory::No, LockBackForwardList::No, NeverSendReferrer, ShouldOpenExternalURLsPolicy::ShouldAllow);
 }
 
 void PDFPlugin::setActiveAnnotation(PDFAnnotation *annotation)
index 00f2737..547c965 100644 (file)
@@ -1540,7 +1540,7 @@ void WebPage::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint do
     auto mouseEvent = MouseEvent::create(eventNames().clickEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes, Event::IsComposed::Yes,
         MonotonicTime::now(), nullptr, singleClick, screenPoint, documentPoint, { }, { }, 0, 0, nullptr, 0, WebCore::NoTap, nullptr);
 
-    mainFrame->loader().urlSelected(mainFrameDocument->completeURL(url), emptyString(), mouseEvent.ptr(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
+    mainFrame->loader().urlSelected(mainFrameDocument->completeURL(url), emptyString(), mouseEvent.ptr(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::NeverSendReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
 }
 
 void WebPage::stopLoadingFrame(uint64_t frameID)
index c85c4e7..125ddda 100644 (file)
@@ -1,3 +1,13 @@
+2019-04-17  Brady Eidson  <beidson@apple.com>
+
+        Link clicks in PDFs shouldn't send referrer headers.
+        <rdar://problem/21142581> and https://bugs.webkit.org/show_bug.cgi?id=196980
+
+        Reviewed by Tim Horton.
+
+        * WebView/WebPDFViewPlaceholder.mm:
+        (-[WebPDFViewPlaceholder simulateClickOnLinkToURL:]):
+
 2019-04-10  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: save sheet should be anchored underneath the tab bar when detached
index a59198c..8348597 100644 (file)
@@ -470,7 +470,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]);
-    FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), { URL }, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow,  InitiatedByMainFrame::Unknown };
+    FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), { URL }, { }, LockHistory::No, LockBackForwardList::No, NeverSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow,  InitiatedByMainFrame::Unknown };
     frame->loader().loadFrameRequest(WTFMove(frameLoadRequest), event.ptr(), nullptr);
 }
 
index 70758a3..d08a24c 100644 (file)
@@ -1,3 +1,13 @@
+2019-04-17  Brady Eidson  <beidson@apple.com>
+
+        Link clicks in PDFs shouldn't send referrer headers.
+        <rdar://problem/21142581> and https://bugs.webkit.org/show_bug.cgi?id=196980
+
+        Reviewed by Tim Horton.
+
+        * WebView/WebPDFView.mm:
+        (-[WebPDFView PDFViewWillClickOnLink:withURL:]):
+
 2019-04-10  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         requestAnimationFrame should execute before the next frame
index 3221d60..786925e 100644 (file)
@@ -991,7 +991,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]);
-    FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), { URL }, { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow, InitiatedByMainFrame::Unknown };
+    FrameLoadRequest frameLoadRequest { *frame->document(), frame->document()->securityOrigin(), { URL }, { }, LockHistory::No, LockBackForwardList::No, NeverSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow, InitiatedByMainFrame::Unknown };
     frame->loader().loadFrameRequest(WTFMove(frameLoadRequest), event.get(), nullptr);
 }
 
index 72cf37a..1b8164c 100644 (file)
@@ -1,3 +1,17 @@
+2019-04-17  Brady Eidson  <beidson@apple.com>
+
+        Link clicks in PDFs shouldn't send referrer headers.
+        <rdar://problem/21142581> and https://bugs.webkit.org/show_bug.cgi?id=196980
+
+        Reviewed by Tim Horton.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/PDFLinkReferrer.mm: Added.
+        (putPDFBytesCallback):
+        (emptyReleaseInfoCallback):
+        (createPDFWithLinkToURL):
+        (TEST):
+
 2019-04-17  Tim Horton  <timothy_horton@apple.com>
 
         UI↔Web deadlock when printing with a JavaScript alert visible
index 7b44d80..059fc0d 100644 (file)
                51CD1C721B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51CD1C711B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html */; };
                51D124981E763B02002B2820 /* WKHTTPCookieStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51D124971E763AF8002B2820 /* WKHTTPCookieStore.mm */; };
                51D1249B1E785425002B2820 /* CookieManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6F3F29013342FEB00A6BF19 /* CookieManager.cpp */; };
+               51D8C1902267B26D00797E40 /* PDFLinkReferrer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51D8C18F2267B26700797E40 /* PDFLinkReferrer.mm */; };
                51DB16CE1F085137001FA4C5 /* WebViewIconLoading.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51DB16CD1F085047001FA4C5 /* WebViewIconLoading.mm */; };
                51E5C7021919C3B200D8B3E1 /* simple2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51E780361919AFF8001829A2 /* simple2.html */; };
                51E5C7031919C3B200D8B3E1 /* simple3.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51E780371919AFF8001829A2 /* simple3.html */; };
                51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ModalAlerts.mm; sourceTree = "<group>"; };
                51CD1C711B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "modal-alerts-in-new-about-blank-window.html"; sourceTree = "<group>"; };
                51D124971E763AF8002B2820 /* WKHTTPCookieStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKHTTPCookieStore.mm; sourceTree = "<group>"; };
+               51D8C18F2267B26700797E40 /* PDFLinkReferrer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PDFLinkReferrer.mm; sourceTree = "<group>"; };
                51DB16CD1F085047001FA4C5 /* WebViewIconLoading.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebViewIconLoading.mm; sourceTree = "<group>"; };
                51E5C7041919EA5F00D8B3E1 /* ShouldKeepCurrentBackForwardListItemInList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShouldKeepCurrentBackForwardListItemInList.cpp; sourceTree = "<group>"; };
                51E6A8921D2F1BEC00C004B6 /* LocalStorageClear.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LocalStorageClear.mm; sourceTree = "<group>"; };
                                F457A9B6202D5CDC00F7E9D5 /* PasteMixedContent.mm */,
                                9BDD95561F83683600D20C60 /* PasteRTFD.mm */,
                                9B2346411F943A2400DB1D23 /* PasteWebArchive.mm */,
+                               51D8C18F2267B26700797E40 /* PDFLinkReferrer.mm */,
                                3FCC4FE41EC4E8520076E37C /* PictureInPictureDelegate.mm */,
                                83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */,
                                C95501BE19AD2FAF0049BE3E /* Preferences.mm */,
                                F457A9B8202D5CDC00F7E9D5 /* PasteMixedContent.mm in Sources */,
                                9BDD95581F83683600D20C60 /* PasteRTFD.mm in Sources */,
                                9B2346421F943E2700DB1D23 /* PasteWebArchive.mm in Sources */,
+                               51D8C1902267B26D00797E40 /* PDFLinkReferrer.mm in Sources */,
                                7C83E0531D0A643A00FEBCF3 /* PendingAPIRequestURL.cpp in Sources */,
                                3FCC4FE51EC4E8520076E37C /* PictureInPictureDelegate.mm in Sources */,
                                7CCE7EAF1A411A3800447C4C /* PlatformUtilities.cpp in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/PDFLinkReferrer.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/PDFLinkReferrer.mm
new file mode 100644 (file)
index 0000000..345124f
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#if PLATFORM(MAC)
+
+#import "TCPServer.h"
+#import "Test.h"
+#import "TestNavigationDelegate.h"
+#import "TestWKWebView.h"
+#import "Utilities.h"
+#import <WebKit/WKFoundation.h>
+
+static size_t putPDFBytesCallback(void* info, void* buffer, size_t count)
+{
+    [(NSMutableData *)info appendBytes:buffer length:count];
+    return count;
+}
+
+static void emptyReleaseInfoCallback(void* __nullable)
+{
+}
+
+static RetainPtr<NSData> createPDFWithLinkToURL(NSURL *url)
+{
+    auto pdfData = adoptNS([[NSMutableData alloc] init]);
+    
+    CGDataConsumerCallbacks callbacks;
+    callbacks.putBytes = (CGDataConsumerPutBytesCallback)putPDFBytesCallback;
+    callbacks.releaseConsumer = (CGDataConsumerReleaseInfoCallback)emptyReleaseInfoCallback;
+    auto consumer = adoptCF(CGDataConsumerCreate(pdfData.get(), &callbacks));
+    auto contextDictionary = adoptCF(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+    CGRect rectangle = CGRectMake(0, 0, 1000, 1000);
+    auto pdfContext = adoptCF(CGPDFContextCreate(consumer.get(), &rectangle, contextDictionary.get()));
+
+    auto pageDictionary = adoptCF(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+    auto boxData = adoptCF(CFDataCreate(NULL, (const UInt8 *)&rectangle, sizeof(CGRect)));
+    CFDictionarySetValue(pageDictionary.get(), kCGPDFContextMediaBox, boxData.get());
+    CGPDFContextBeginPage(pdfContext.get(), pageDictionary.get());
+    
+    CGContextSetRGBFillColor(pdfContext.get(), 1.0, 0.0, 0.0, 1.0);
+    CGContextSetRGBStrokeColor(pdfContext.get(), 1.0, 0.0, 0.0, 1.0);
+    CGContextFillRect(pdfContext.get(), rectangle);
+    CGPDFContextSetURLForRect(pdfContext.get(), (CFURLRef)url, rectangle);
+    CGPDFContextEndPage(pdfContext.get());
+
+    return pdfData;
+}
+
+TEST(WebKit, PDFLinkReferrer)
+{
+    TestWebKitAPI::TCPServer server([] (auto socket) {
+        char readBuffer[1000];
+        memset(readBuffer, 0, 1000);
+
+        // This assumes all the data from the HTTP request is available to be read at once,
+        // which is probably an okay assumption.
+        ::read(socket, readBuffer, 999);
+
+        // Look for a referer header.
+        char* currentLine = readBuffer;
+        while (currentLine) {
+            EXPECT_NE(strncasecmp(currentLine, "referer:", 8), 0);
+            char* nextLine = strchr(currentLine, '\n');
+            currentLine = nextLine ? nextLine + 1 : 0;
+        }
+
+        const char* responseHeader =
+        "HTTP/1.1 200 OK\r\n"
+        "Content-Length: 0\r\n\r\n";
+        ::write(socket, responseHeader, strlen(responseHeader));
+    });
+
+    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+
+    auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
+    webView.get().navigationDelegate = navigationDelegate.get();
+
+    auto *linkURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%hu", server.port()]];
+    auto pdfData = createPDFWithLinkToURL(linkURL);
+
+    [webView loadData:pdfData.get() MIMEType:@"application/pdf" characterEncodingName:@"" baseURL:linkURL];
+    [navigationDelegate waitForDidFinishNavigation];
+
+    navigationDelegate.get().decidePolicyForNavigationAction = ^(WKNavigationAction *action, void (^decisionHandler)(WKNavigationActionPolicy)) {
+        EXPECT_NULL([action.request valueForHTTPHeaderField:@"Referer"]);
+        decisionHandler(WKNavigationActionPolicyAllow);
+    };
+    
+    [webView sendClicksAtPoint:NSMakePoint(75, 75) numberOfClicks:1];
+    [navigationDelegate waitForDidFinishNavigation];
+
+}
+
+#endif // PLATFORM(MAC)