WebKit Bugzilla
Attachment 342446 Details for
Bug 185273
: Use SafeBrowsing in WKWebView
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
bug-185273-20180611135749.patch (text/plain), 130.79 KB, created by
Ali Juma
on 2018-06-11 10:57:50 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Ali Juma
Created:
2018-06-11 10:57:50 PDT
Size:
130.79 KB
patch
obsolete
>Subversion Revision: 232712 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 9519e646cfd2927cede5abbb50e55384eb052f34..40e64351f218739288477868c4d758b2388b3f0a 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,55 @@ >+2018-06-11 Ali Juma <ajuma@chromium.org> >+ >+ Use SafeBrowsing in WKWebView >+ https://bugs.webkit.org/show_bug.cgi?id=181804 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add logic to maintain correct back/forward history when displaying or bypassing >+ a SafeBrowsing warning. The existing logic (e.g. for network errors) depends on >+ failing provisional load, but we don't get that far with SafeBrowsing, since >+ we cancel the original load at the navigation policy stage. >+ >+ Add a setting for WebView SafeBrowsing. >+ >+ New API tests: WebKit.SafeBrowsingForSafePage >+ WebKit.SafeBrowsingForUnsafePageAllow >+ WebKit.SafeBrowsingForUnsafePageShowWarning >+ WebKit.SafeBrowsingForUnsafePageShowWarningBackForward >+ WebKit.SafeBrowsingForUnsafePageCancelForSafeBrowsing >+ WebKit.SafeBrowsingForUnsafePageCancelNavigation >+ WebKit.SafeBrowsingForUnsafePageRedirectShowWarning >+ WebKit.SafeBrowsingForUnsafePageRedirectAllow >+ WebKit.SafeBrowsingForUnsafePageRedirectCancel >+ WebKit.SafeBrowsingForUnsafeSubframeShowWarning >+ >+ * loader/DocumentLoader.cpp: >+ (WebCore::DocumentLoader::willSendRequest): >+ * loader/DocumentLoader.h: >+ (WebCore::DocumentLoader::isLoadingSubstituteDataForExistingHistoryItem const): >+ (WebCore::DocumentLoader::setIsLoadingSubstituteDataForExistingHistoryItem): >+ * loader/EmptyClients.cpp: >+ (WebCore::EmptyFrameLoaderClient::dispatchDecidePolicyForNavigationAction): >+ * loader/EmptyFrameLoaderClient.h: >+ * loader/FrameLoadRequest.cpp: >+ (WebCore::FrameLoadRequest::FrameLoadRequest): >+ * loader/FrameLoadRequest.h: >+ (WebCore::FrameLoadRequest::setTargetHistoryItem): >+ (WebCore::FrameLoadRequest::targetHistoryItem const): >+ (WebCore::FrameLoadRequest::setNavigationType): >+ (WebCore::FrameLoadRequest::navigationType const): >+ * loader/FrameLoader.cpp: >+ (WebCore::FrameLoader::loadURL): >+ (WebCore::FrameLoader::load): >+ (WebCore::FrameLoader::loadWithDocumentLoader): >+ (WebCore::FrameLoader::shouldReloadToHandleUnreachableURL): >+ * loader/FrameLoaderClient.h: >+ * loader/FrameLoaderTypes.h: >+ * loader/PolicyChecker.cpp: >+ (WebCore::PolicyChecker::checkNavigationPolicy): >+ * loader/PolicyChecker.h: >+ * page/Settings.yaml: >+ > 2018-06-11 Zalan Bujtas <zalan@apple.com> > > [LFC] Merge left, right, width and horizontal margin computation for out-of-flow non-replaced elements >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index f1afd16924c7fee46c204759ed1075673e07b98d..7e212ed33216d18bd3c951ae35d9786de164fbe5 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,75 @@ >+2018-06-11 Ali Juma <ajuma@chromium.org> >+ >+ Use SafeBrowsing in WKWebView >+ https://bugs.webkit.org/show_bug.cgi?id=181804 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ In parallel with asking the embedder to decidePolicyForNavigationAction, >+ perform a SafeBrowsing look-up. If the embedder's decision is to proceed, >+ but the SafeBrowsing look-up finds that the URL is unsafe, fire a new >+ decidePolicyForSafeBrowsingResultForNavigationAction callback to ask >+ the embedder whether to proceed anyway, to cancel the navigation, or to >+ cancel the navigation and show a default warning page. >+ >+ Add a new safeBrowsingEnabled WKPreference for this new behavior. >+ >+ Add a SafeBrowsingContextProvider for switching between the system-provided >+ SSBLookupContext and the test-only _WKSafeBrowsingLookupContext. >+ >+ * Shared/LoadParameters.cpp: >+ (WebKit::LoadParameters::encode const): >+ (WebKit::LoadParameters::decode): >+ * Shared/LoadParameters.h: >+ * Shared/NavigationActionData.cpp: >+ (WebKit::NavigationActionData::encode const): >+ (WebKit::NavigationActionData::decode): >+ * Shared/NavigationActionData.h: >+ * Shared/WebPreferences.yaml: >+ * UIProcess/API/APINavigationAction.h: >+ * UIProcess/API/Cocoa/WKNavigationDelegate.h: >+ * UIProcess/API/Cocoa/WKPreferences.h: >+ * UIProcess/API/Cocoa/WKPreferences.mm: >+ (-[WKPreferences encodeWithCoder:]): >+ (-[WKPreferences initWithCoder:]): >+ (-[WKPreferences safeBrowsingEnabled]): >+ (-[WKPreferences setSafeBrowsingEnabled:]): >+ * UIProcess/API/Cocoa/WKWebView.mm: >+ (-[WKWebView _setUseTestSafeBrowsingContext:]): >+ * UIProcess/API/Cocoa/WKWebViewPrivate.h: >+ * UIProcess/Cocoa/NavigationState.h: >+ * UIProcess/Cocoa/NavigationState.mm: >+ (WebKit::NavigationState::NavigationState): >+ (WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction): >+ (WebKit::NavigationState::NavigationClient::decidePolicyForNavigationActionInternal): >+ * UIProcess/Cocoa/SafeBrowsingContextProvider.h: Added. >+ (WebKit::SafeBrowsingContextProvider::setUseTestContext): >+ * UIProcess/Cocoa/SafeBrowsingContextProvider.mm: Added. >+ (+[_WKSafeBrowsingTestLookupContext sharedLookupContext]): >+ (-[_WKSafeBrowsingTestLookupContext lookUpURL:completionHandler:]): >+ (WebKit::SafeBrowsingContextProvider::sharedLookupContext): >+ * UIProcess/Cocoa/SafeBrowsingController.h: Added. >+ (WebKit::SafeBrowsingController::SafeBrowsingCheck::SafeBrowsingCheck): >+ * UIProcess/Cocoa/SafeBrowsingController.mm: Added. >+ (WebKit::SafeBrowsingController::SafeBrowsingController): >+ (WebKit::SafeBrowsingController::~SafeBrowsingController): >+ (WebKit::SafeBrowsingController::checkURL): >+ (WebKit::SafeBrowsingController::receivedNavigationPolicyDecision): >+ (WebKit::SafeBrowsingController::receivedSafeBrowsingResult): >+ (WebKit::SafeBrowsingController::maybeFinishedCheck): >+ * UIProcess/WebPageProxy.cpp: >+ (WebKit::WebPageProxy::loadAlternateHTMLString): >+ * UIProcess/WebPageProxy.h: >+ * WebKit.xcodeproj/project.pbxproj: >+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: >+ (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction): >+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.h: >+ * WebProcess/WebPage/WebPage.cpp: >+ (WebKit::WebPage::loadDataImpl): >+ (WebKit::WebPage::loadStringImpl): >+ (WebKit::WebPage::loadAlternateHTMLString): >+ * WebProcess/WebPage/WebPage.h: >+ > 2018-06-10 Carlos Garcia Campos <cgarcia@igalia.com> > > [GTK][WPE] Add API run run javascript from a WebKitWebView in an isolated world >diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog >index 4205ea3a36b20217d4ba487b873176cfe62b471a..357149b7896a8ad8151f0df3d9eab9c68111c5c4 100644 >--- a/Source/WebKitLegacy/mac/ChangeLog >+++ b/Source/WebKitLegacy/mac/ChangeLog >@@ -1,3 +1,14 @@ >+2018-06-11 Ali Juma <ajuma@chromium.org> >+ >+ Use SafeBrowsing in WKWebView >+ https://bugs.webkit.org/show_bug.cgi?id=185273 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebCoreSupport/WebFrameLoaderClient.h: >+ * WebCoreSupport/WebFrameLoaderClient.mm: >+ (WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction): >+ > 2018-06-09 Dan Bernstein <mitz@apple.com> > > [Xcode] Clean up and modernize some build setting definitions >diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp >index fb07ee53bd5a4a40dc648ab5339ca0cc54e1269e..87ec9908aec1607ce1f6e1671274c44392e0c0ad 100644 >--- a/Source/WebCore/loader/DocumentLoader.cpp >+++ b/Source/WebCore/loader/DocumentLoader.cpp >@@ -657,7 +657,7 @@ void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const Resourc > return; > } > >- frameLoader()->policyChecker().checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, WTFMove(navigationPolicyCompletionHandler)); >+ frameLoader()->policyChecker().checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, RedirectedByClient::No, WTFMove(navigationPolicyCompletionHandler)); > } > > bool DocumentLoader::tryLoadingRequestFromApplicationCache() >diff --git a/Source/WebCore/loader/DocumentLoader.h b/Source/WebCore/loader/DocumentLoader.h >index 9f9a8221ad8a3fd2f9be3cc502d5a6ec858e39e6..7040c07f28f4f2baad21af80775d7a035f5c98f9 100644 >--- a/Source/WebCore/loader/DocumentLoader.h >+++ b/Source/WebCore/loader/DocumentLoader.h >@@ -170,6 +170,8 @@ public: > > bool isClientRedirect() const { return m_isClientRedirect; } > void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; } >+ bool isLoadingSubstituteDataForExistingHistoryItem() const { return m_isLoadingSubstituteDataForExistingHistoryItem; } >+ void setIsLoadingSubstituteDataForExistingHistoryItem(bool isLoadingSubstituteDataForExistingHistoryItem) { m_isLoadingSubstituteDataForExistingHistoryItem = isLoadingSubstituteDataForExistingHistoryItem; } > void dispatchOnloadEvents(); > bool wasOnloadDispatched() { return m_wasOnloadDispatched; } > WEBCORE_EXPORT bool isLoadingInAPISense() const; >@@ -450,6 +452,7 @@ private: > bool m_gotFirstByte { false }; > bool m_isClientRedirect { false }; > bool m_isLoadingMultipartContent { false }; >+ bool m_isLoadingSubstituteDataForExistingHistoryItem { false }; > > // FIXME: Document::m_processingLoadEvent and DocumentLoader::m_wasOnloadDispatched are roughly the same > // and should be merged. >diff --git a/Source/WebCore/loader/EmptyClients.cpp b/Source/WebCore/loader/EmptyClients.cpp >index 6053b878b2f0454003df14701ea8cba4d039dac7..40b609c07bbcbe7fa08c7b1ff56fd00eadf79bb2 100644 >--- a/Source/WebCore/loader/EmptyClients.cpp >+++ b/Source/WebCore/loader/EmptyClients.cpp >@@ -446,7 +446,7 @@ void EmptyFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const Naviga > { > } > >-void EmptyFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool, FormState*, PolicyDecisionMode, FramePolicyFunction&&) >+void EmptyFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool, RedirectedByClient, FormState*, PolicyDecisionMode, FramePolicyFunction&&) > { > } > >diff --git a/Source/WebCore/loader/EmptyFrameLoaderClient.h b/Source/WebCore/loader/EmptyFrameLoaderClient.h >index 34a508ab58c6d67ade235779603d47d9d423a928..9d0cb9e69c147ac5aa4b75ac78363c3686e99e12 100644 >--- a/Source/WebCore/loader/EmptyFrameLoaderClient.h >+++ b/Source/WebCore/loader/EmptyFrameLoaderClient.h >@@ -95,7 +95,7 @@ class WEBCORE_EXPORT EmptyFrameLoaderClient : public FrameLoaderClient { > > void dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, FramePolicyFunction&&) final { } > void dispatchDecidePolicyForNewWindowAction(const NavigationAction&, const ResourceRequest&, FormState*, const String&, FramePolicyFunction&&) final; >- void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool didReceiveRedirectResponse, FormState*, PolicyDecisionMode, FramePolicyFunction&&) final; >+ void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool didReceiveRedirectResponse, RedirectedByClient, FormState*, PolicyDecisionMode, FramePolicyFunction&&) final; > void cancelPolicyCheck() final { } > > void dispatchUnableToImplementPolicy(const ResourceError&) final { } >diff --git a/Source/WebCore/loader/FrameLoadRequest.cpp b/Source/WebCore/loader/FrameLoadRequest.cpp >index aaacbaccc1fc9263984f649369dd159673cf2d91..c62bdc632b9c0cccbf7a7f9212765d3894b65156 100644 >--- a/Source/WebCore/loader/FrameLoadRequest.cpp >+++ b/Source/WebCore/loader/FrameLoadRequest.cpp >@@ -55,18 +55,20 @@ FrameLoadRequest::FrameLoadRequest(Document& requester, SecurityOrigin& requeste > { > } > >-FrameLoadRequest::FrameLoadRequest(Frame& frame, const ResourceRequest& resourceRequest, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, const SubstituteData& substituteData) >+FrameLoadRequest::FrameLoadRequest(Frame& frame, const ResourceRequest& resourceRequest, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, const SubstituteData& substituteData, LockBackForwardList lockBackForwardList, NavigationType navigationType, HistoryItem* targetHistoryItem) > : m_requester { makeRef(*frame.document()) } > , m_requesterSecurityOrigin { makeRef(frame.document()->securityOrigin()) } > , m_resourceRequest { resourceRequest } > , m_substituteData { substituteData } > , m_lockHistory { LockHistory::No } >- , m_lockBackForwardList { LockBackForwardList::No } >+ , m_lockBackForwardList { lockBackForwardList } > , m_shouldSendReferrer { MaybeSendReferrer } > , m_allowNavigationToInvalidURL { AllowNavigationToInvalidURL::Yes } > , m_newFrameOpenerPolicy { NewFrameOpenerPolicy::Allow } > , m_shouldReplaceDocumentIfJavaScriptURL { ReplaceDocumentIfJavaScriptURL } > , m_shouldOpenExternalURLsPolicy { shouldOpenExternalURLsPolicy } >+ , m_targetHistoryItem { targetHistoryItem } >+ , m_navigationType { navigationType } > { > } > >diff --git a/Source/WebCore/loader/FrameLoadRequest.h b/Source/WebCore/loader/FrameLoadRequest.h >index 049ba47ce481b4f8dd48c32f6ff780a31a3c523d..24d189a5620b68a7dd559b88c6c151d27a8760c6 100644 >--- a/Source/WebCore/loader/FrameLoadRequest.h >+++ b/Source/WebCore/loader/FrameLoadRequest.h >@@ -34,12 +34,13 @@ namespace WebCore { > > class Document; > class Frame; >+class HistoryItem; > class SecurityOrigin; > > class FrameLoadRequest { > public: > WEBCORE_EXPORT FrameLoadRequest(Document&, SecurityOrigin&, const ResourceRequest&, const String& frameName, LockHistory, LockBackForwardList, ShouldSendReferrer, AllowNavigationToInvalidURL, NewFrameOpenerPolicy, ShouldOpenExternalURLsPolicy, InitiatedByMainFrame, ShouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute = { }, const SystemPreviewInfo& = { }); >- WEBCORE_EXPORT FrameLoadRequest(Frame&, const ResourceRequest&, ShouldOpenExternalURLsPolicy, const SubstituteData& = SubstituteData()); >+ WEBCORE_EXPORT FrameLoadRequest(Frame&, const ResourceRequest&, ShouldOpenExternalURLsPolicy, const SubstituteData& = SubstituteData(), LockBackForwardList = LockBackForwardList::No, NavigationType = NavigationType::Other, HistoryItem* targetHistoryItem = nullptr); > > WEBCORE_EXPORT ~FrameLoadRequest(); > >@@ -90,6 +91,12 @@ public: > bool isSystemPreview() const { return m_systemPreviewInfo.isSystemPreview; } > const IntRect& systemPreviewRect() const { return m_systemPreviewInfo.systemPreviewRect; } > >+ void setTargetHistoryItem(HistoryItem* item) { m_targetHistoryItem = item; } >+ HistoryItem* targetHistoryItem() const { return m_targetHistoryItem; } >+ >+ void setNavigationType(NavigationType navigationType) { m_navigationType = navigationType; } >+ NavigationType navigationType() const { return m_navigationType; } >+ > private: > Ref<Document> m_requester; > Ref<SecurityOrigin> m_requesterSecurityOrigin; >@@ -110,6 +117,8 @@ private: > InitiatedByMainFrame m_initiatedByMainFrame { InitiatedByMainFrame::Unknown }; > bool m_isCrossOriginWindowOpenNavigation { false }; > SystemPreviewInfo m_systemPreviewInfo; >+ HistoryItem* m_targetHistoryItem { nullptr }; >+ NavigationType m_navigationType { NavigationType::Other }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp >index 3fb4f280fa06e80c63d549478782c4357bb549b7..ed63b71a75314ebff4a846091a94dac92584c576 100644 >--- a/Source/WebCore/loader/FrameLoader.cpp >+++ b/Source/WebCore/loader/FrameLoader.cpp >@@ -1379,7 +1379,7 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref > oldDocumentLoader->setLastCheckedRequest(ResourceRequest()); > policyChecker().stopCheck(); > policyChecker().setLoadType(newLoadType); >- policyChecker().checkNavigationPolicy(WTFMove(request), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) { >+ policyChecker().checkNavigationPolicy(WTFMove(request), false /* didReceiveRedirectResponse */, RedirectedByClient::No, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) { > continueFragmentScrollAfterNavigationPolicy(request, shouldContinue == ShouldContinue::Yes); > }, PolicyDecisionMode::Synchronous); > return; >@@ -1454,6 +1454,23 @@ void FrameLoader::load(FrameLoadRequest&& request) > addSameSiteInfoToRequestIfNeeded(loader->request()); > applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, request); > >+ if (request.lockBackForwardList() == LockBackForwardList::Yes) { >+ m_loadType = FrameLoadType::RedirectWithLockedBackForwardList; >+ loader->setIsClientRedirect(true); >+ if (request.hasSubstituteData() && !request.substituteData().failingURL().isEmpty()) >+ history().currentItem()->setURL(request.substituteData().failingURL()); >+ } else if (HistoryItem* targetItem = request.targetHistoryItem()) { >+ ASSERT(request.navigationType() == NavigationType::BackForward); >+ m_loadType = FrameLoadType::IndexedBackForward; >+ history().setProvisionalItem(targetItem); >+ loader->setIsLoadingSubstituteDataForExistingHistoryItem(true); >+ if (Page* page = m_frame.page()) { >+ page->backForward().setCurrentItem(targetItem); >+ m_frame.loader().client().updateGlobalHistoryItemForPage(); >+ } >+ } else if (request.navigationType() == NavigationType::Reload) >+ m_loadType = FrameLoadType::Reload; >+ > SetForScope<bool> currentLoadShouldCheckNavigationPolicyGuard(m_currentLoadShouldCheckNavigationPolicy, request.shouldCheckNavigationPolicy()); > load(loader.ptr()); > } >@@ -1554,7 +1571,7 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t > oldDocumentLoader->setTriggeringAction(action); > oldDocumentLoader->setLastCheckedRequest(ResourceRequest()); > policyChecker().stopCheck(); >- policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) { >+ policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, RedirectedByClient::No, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) { > continueFragmentScrollAfterNavigationPolicy(request, shouldContinue == ShouldContinue::Yes); > }, PolicyDecisionMode::Synchronous); > return; >@@ -1588,7 +1605,8 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t > return; > } > >- policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, loader, WTFMove(formState), [this, protectedFrame = makeRef(m_frame), allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, ShouldContinue shouldContinue) { >+ RedirectedByClient redirectedByClient = m_quickRedirectComing ? RedirectedByClient::Yes : RedirectedByClient::No; >+ policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, redirectedByClient, loader, WTFMove(formState), [this, protectedFrame = makeRef(m_frame), allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, ShouldContinue shouldContinue) { > continueLoadAfterNavigationPolicy(request, formState.get(), shouldContinue, allowNavigationToInvalidURL); > completionHandler(); > }); >@@ -1673,7 +1691,7 @@ bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader* docLoader) > if (policyChecker().delegateIsDecidingNavigationPolicy() || policyChecker().delegateIsHandlingUnimplementablePolicy()) > return m_policyDocumentLoader && unreachableURL == m_policyDocumentLoader->request().url(); > >- return unreachableURL == m_provisionalLoadErrorBeingHandledURL; >+ return unreachableURL == m_provisionalLoadErrorBeingHandledURL || docLoader->isLoadingSubstituteDataForExistingHistoryItem(); > } > > void FrameLoader::reloadWithOverrideEncoding(const String& encoding) >diff --git a/Source/WebCore/loader/FrameLoaderClient.h b/Source/WebCore/loader/FrameLoaderClient.h >index c6f67de13782a7320c506305993989b0ac2254e7..90b19df6508e140f8f68453fe69539b9068c1116 100644 >--- a/Source/WebCore/loader/FrameLoaderClient.h >+++ b/Source/WebCore/loader/FrameLoaderClient.h >@@ -191,7 +191,7 @@ public: > > virtual void dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, FramePolicyFunction&&) = 0; > virtual void dispatchDecidePolicyForNewWindowAction(const NavigationAction&, const ResourceRequest&, FormState*, const String& frameName, FramePolicyFunction&&) = 0; >- virtual void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool didReceiveRedirectResponse, FormState*, PolicyDecisionMode, FramePolicyFunction&&) = 0; >+ virtual void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool didReceiveRedirectResponse, RedirectedByClient, FormState*, PolicyDecisionMode, FramePolicyFunction&&) = 0; > virtual void cancelPolicyCheck() = 0; > > virtual void dispatchUnableToImplementPolicy(const ResourceError&) = 0; >diff --git a/Source/WebCore/loader/FrameLoaderTypes.h b/Source/WebCore/loader/FrameLoaderTypes.h >index bd183913b598871e3fa64a57c0c6564642876b06..8cb57d90c7377febebc34794f759e52aafbde5b6 100644 >--- a/Source/WebCore/loader/FrameLoaderTypes.h >+++ b/Source/WebCore/loader/FrameLoaderTypes.h >@@ -149,6 +149,11 @@ enum class HasInsecureContent { > No, > }; > >+enum class RedirectedByClient { >+ Yes, >+ No >+}; >+ > > struct SystemPreviewInfo { > IntRect systemPreviewRect; >@@ -193,4 +198,12 @@ template<> struct EnumTraits<WebCore::FrameLoadType> { > >; > }; > >+template<> struct EnumTraits<WebCore::RedirectedByClient> { >+ using values = EnumValues< >+ WebCore::RedirectedByClient, >+ WebCore::RedirectedByClient::Yes, >+ WebCore::RedirectedByClient::No >+ >; >+}; >+ > } // namespace WTF >diff --git a/Source/WebCore/loader/PolicyChecker.cpp b/Source/WebCore/loader/PolicyChecker.cpp >index 5f9751cb6e3e90440c090ed8f6278e0c059954f8..d9c199b9864cc6902093e776514eea61a7f73186 100644 >--- a/Source/WebCore/loader/PolicyChecker.cpp >+++ b/Source/WebCore/loader/PolicyChecker.cpp >@@ -79,9 +79,9 @@ PolicyChecker::PolicyChecker(Frame& frame) > { > } > >-void PolicyChecker::checkNavigationPolicy(ResourceRequest&& newRequest, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&& function) >+void PolicyChecker::checkNavigationPolicy(ResourceRequest&& newRequest, bool didReceiveRedirectResponse, RedirectedByClient redirectedByClient, NavigationPolicyDecisionFunction&& function) > { >- checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, m_frame.loader().activeDocumentLoader(), { }, WTFMove(function)); >+ checkNavigationPolicy(WTFMove(newRequest), didReceiveRedirectResponse, redirectedByClient, m_frame.loader().activeDocumentLoader(), { }, WTFMove(function)); > } > > CompletionHandlerCallingScope PolicyChecker::extendBlobURLLifetimeIfNecessary(ResourceRequest& request) const >@@ -98,7 +98,7 @@ CompletionHandlerCallingScope PolicyChecker::extendBlobURLLifetimeIfNecessary(Re > }); > } > >-void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didReceiveRedirectResponse, DocumentLoader* loader, RefPtr<FormState>&& formState, NavigationPolicyDecisionFunction&& function, PolicyDecisionMode policyDecisionMode) >+void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didReceiveRedirectResponse, RedirectedByClient redirectedByClient, DocumentLoader* loader, RefPtr<FormState>&& formState, NavigationPolicyDecisionFunction&& function, PolicyDecisionMode policyDecisionMode) > { > NavigationAction action = loader->triggeringAction(); > if (action.isEmpty()) { >@@ -168,7 +168,7 @@ void PolicyChecker::checkNavigationPolicy(ResourceRequest&& request, bool didRec > > m_delegateIsDecidingNavigationPolicy = true; > String suggestedFilename = action.downloadAttribute().isEmpty() ? nullAtom() : action.downloadAttribute(); >- m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, formState.get(), policyDecisionMode, [this, function = WTFMove(function), request = ResourceRequest(request), formState = WTFMove(formState), suggestedFilename = WTFMove(suggestedFilename), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable { >+ m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, redirectedByClient, formState.get(), policyDecisionMode, [this, function = WTFMove(function), request = ResourceRequest(request), formState = WTFMove(formState), suggestedFilename = WTFMove(suggestedFilename), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable { > m_delegateIsDecidingNavigationPolicy = false; > > switch (policyAction) { >diff --git a/Source/WebCore/loader/PolicyChecker.h b/Source/WebCore/loader/PolicyChecker.h >index 9f0489738191935c33d9c72cb05518a3708fa8aa..bf39e38990d892e5bec2e612558a005aa6b0a4df 100644 >--- a/Source/WebCore/loader/PolicyChecker.h >+++ b/Source/WebCore/loader/PolicyChecker.h >@@ -69,8 +69,8 @@ class PolicyChecker { > public: > explicit PolicyChecker(Frame&); > >- void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, DocumentLoader*, RefPtr<FormState>&&, NavigationPolicyDecisionFunction&&, PolicyDecisionMode = PolicyDecisionMode::Asynchronous); >- void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, NavigationPolicyDecisionFunction&&); >+ void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, RedirectedByClient, DocumentLoader*, RefPtr<FormState>&&, NavigationPolicyDecisionFunction&&, PolicyDecisionMode = PolicyDecisionMode::Asynchronous); >+ void checkNavigationPolicy(ResourceRequest&&, bool didReceiveRedirectResponse, RedirectedByClient, NavigationPolicyDecisionFunction&&); > void checkNewWindowPolicy(NavigationAction&&, ResourceRequest&&, RefPtr<FormState>&&, const String& frameName, NewWindowPolicyDecisionFunction&&); > > void stopCheck(); >diff --git a/Source/WebCore/page/Settings.yaml b/Source/WebCore/page/Settings.yaml >index dd9ed86fa1554cf7d76e49a1fe9667112ee6609a..a5716ea81b9a6d710b570b065671314241425dc4 100644 >--- a/Source/WebCore/page/Settings.yaml >+++ b/Source/WebCore/page/Settings.yaml >@@ -689,6 +689,9 @@ shouldAllowUserInstalledFonts: > initial: true > onChange: setNeedsRecalcStyleInAllFrames > >+safeBrowsingEnabled: >+ initial: false >+ > # Only set by Layout Tests. > mediaTypeOverride: > type: String >diff --git a/Source/WebKit/Shared/LoadParameters.cpp b/Source/WebKit/Shared/LoadParameters.cpp >index a6791efa074dfe50d59fe0a1ce6feea246d3d5fe..8bc60a47ba63580adea2d210ee101d73259ad256 100644 >--- a/Source/WebKit/Shared/LoadParameters.cpp >+++ b/Source/WebKit/Shared/LoadParameters.cpp >@@ -50,6 +50,9 @@ void LoadParameters::encode(IPC::Encoder& encoder) const > encoder << shouldOpenExternalURLsPolicy; > encoder << shouldCheckNavigationPolicy; > encoder << userData; >+ encoder.encodeEnum(redirectedByClient); >+ encoder.encodeEnum(navigationType); >+ encoder << targetBackForwardItemIdentifier; > > platformEncode(encoder); > } >@@ -109,6 +112,18 @@ bool LoadParameters::decode(IPC::Decoder& decoder, LoadParameters& data) > if (!decoder.decode(data.userData)) > return false; > >+ if (!decoder.decodeEnum(data.redirectedByClient)) >+ return false; >+ >+ if (!decoder.decodeEnum(data.navigationType)) >+ return false; >+ >+ std::optional<std::optional<WebCore::BackForwardItemIdentifier>> targetBackForwardItemIdentifier; >+ decoder >> targetBackForwardItemIdentifier; >+ if (!targetBackForwardItemIdentifier) >+ return false; >+ data.targetBackForwardItemIdentifier = WTFMove(*targetBackForwardItemIdentifier); >+ > if (!platformDecode(decoder, data)) > return false; > >diff --git a/Source/WebKit/Shared/LoadParameters.h b/Source/WebKit/Shared/LoadParameters.h >index 8402ddc85002a5aca0ce01f310caebab08f1fd5c..4d7138da7d7eccbc046e75c6740404bd10358261 100644 >--- a/Source/WebKit/Shared/LoadParameters.h >+++ b/Source/WebKit/Shared/LoadParameters.h >@@ -29,6 +29,8 @@ > #include "DataReference.h" > #include "SandboxExtension.h" > #include "UserData.h" >+#include <WebCore/BackForwardItemIdentifier.h> >+#include <WebCore/FrameLoaderTypes.h> > #include <WebCore/ResourceRequest.h> > > OBJC_CLASS NSDictionary; >@@ -65,6 +67,10 @@ struct LoadParameters { > bool shouldCheckNavigationPolicy { true }; > UserData userData; > >+ WebCore::RedirectedByClient redirectedByClient; >+ WebCore::NavigationType navigationType; >+ std::optional<WebCore::BackForwardItemIdentifier> targetBackForwardItemIdentifier; >+ > #if PLATFORM(COCOA) > RetainPtr<NSDictionary> dataDetectionContext; > #endif >diff --git a/Source/WebKit/Shared/NavigationActionData.cpp b/Source/WebKit/Shared/NavigationActionData.cpp >index e61b2acaa1f70e7d05bca7fb4990aed2950714d6..dc5454c6995e5f54d2caffb9266929f61e780bd3 100644 >--- a/Source/WebKit/Shared/NavigationActionData.cpp >+++ b/Source/WebKit/Shared/NavigationActionData.cpp >@@ -47,6 +47,7 @@ void NavigationActionData::encode(IPC::Encoder& encoder) const > encoder << downloadAttribute; > encoder << clickLocationInRootViewCoordinates; > encoder << isRedirect; >+ encoder << redirectedByClient; > encoder << treatAsSameOriginNavigation; > encoder << isCrossOriginWindowOpenNavigation; > encoder << opener; >@@ -99,6 +100,10 @@ std::optional<NavigationActionData> NavigationActionData::decode(IPC::Decoder& d > if (!isRedirect) > return std::nullopt; > >+ WebCore::RedirectedByClient redirectedByClient; >+ if (!decoder.decodeEnum(redirectedByClient)) >+ return std::nullopt; >+ > std::optional<bool> treatAsSameOriginNavigation; > decoder >> treatAsSameOriginNavigation; > if (!treatAsSameOriginNavigation) >@@ -121,7 +126,7 @@ std::optional<NavigationActionData> NavigationActionData::decode(IPC::Decoder& d > > return {{ WTFMove(navigationType), WTFMove(modifiers), WTFMove(mouseButton), WTFMove(syntheticClickType), WTFMove(*userGestureTokenIdentifier), > WTFMove(*canHandleRequest), WTFMove(shouldOpenExternalURLsPolicy), WTFMove(*downloadAttribute), WTFMove(clickLocationInRootViewCoordinates), >- WTFMove(*isRedirect), *treatAsSameOriginNavigation, *isCrossOriginWindowOpenNavigation, WTFMove(*opener), WTFMove(*targetBackForwardItemIdentifier) }}; >+ WTFMove(*isRedirect), WTFMove(redirectedByClient), *treatAsSameOriginNavigation, *isCrossOriginWindowOpenNavigation, WTFMove(*opener), WTFMove(*targetBackForwardItemIdentifier) }}; > } > > } // namespace WebKit >diff --git a/Source/WebKit/Shared/NavigationActionData.h b/Source/WebKit/Shared/NavigationActionData.h >index bf73982dd710b1507663ada305057318883fe492..1667122baaa9b97b24f8daa6757a4da3bd4cd4e2 100644 >--- a/Source/WebKit/Shared/NavigationActionData.h >+++ b/Source/WebKit/Shared/NavigationActionData.h >@@ -1,3 +1,4 @@ >+ > /* > * Copyright (C) 2014-2016 Apple Inc. All rights reserved. > * >@@ -51,6 +52,7 @@ struct NavigationActionData { > WTF::String downloadAttribute; > WebCore::FloatPoint clickLocationInRootViewCoordinates; > bool isRedirect { false }; >+ WebCore::RedirectedByClient redirectedByClient { WebCore::RedirectedByClient::No }; > bool treatAsSameOriginNavigation { false }; > bool isCrossOriginWindowOpenNavigation { false }; > std::optional<std::pair<uint64_t, uint64_t>> opener; >diff --git a/Source/WebKit/Shared/WebPreferences.yaml b/Source/WebKit/Shared/WebPreferences.yaml >index 1c2995062cc430a342099e3f8d9b97dd2acc29b2..06f9b9aca48359da2b1c32124aa6570eb8300411 100644 >--- a/Source/WebKit/Shared/WebPreferences.yaml >+++ b/Source/WebKit/Shared/WebPreferences.yaml >@@ -1059,6 +1059,10 @@ MediaCapabilitiesEnabled: > defaultValue: false > webcoreBinding: RuntimeEnabledFeatures > >+SafeBrowsingEnabled: >+ type: bool >+ defaultValue: false >+ > # For experimental features: > # The type should be boolean. > # You must provide a humanReadableName and humanReadableName for all experimental features. They >diff --git a/Source/WebKit/UIProcess/API/APINavigationAction.h b/Source/WebKit/UIProcess/API/APINavigationAction.h >index 6dad89b70254499364cf92848774ab40d17b50b3..0f242d78dd4b4177be3223e18270913cfbf94829 100644 >--- a/Source/WebKit/UIProcess/API/APINavigationAction.h >+++ b/Source/WebKit/UIProcess/API/APINavigationAction.h >@@ -29,6 +29,7 @@ > #include "APIObject.h" > #include "APIUserInitiatedAction.h" > #include "NavigationActionData.h" >+#include <WebCore/BackForwardItemIdentifier.h> > #include <WebCore/ResourceRequest.h> > #include <WebCore/URL.h> > >@@ -58,6 +59,8 @@ public: > bool shouldOpenAppLinks() const { return m_shouldOpenAppLinks && m_navigationActionData.shouldOpenExternalURLsPolicy == WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow; } > bool shouldPerformDownload() const { return !m_navigationActionData.downloadAttribute.isNull(); } > bool isRedirect() const { return m_navigationActionData.isRedirect; } >+ WebCore::RedirectedByClient redirectedByClient() const { return m_navigationActionData.redirectedByClient; } >+ std::optional<WebCore::BackForwardItemIdentifier> targetBackForwardItemIdentifier() const { return m_navigationActionData.targetBackForwardItemIdentifier; } > > bool isProcessingUserGesture() const { return m_userInitiatedAction; } > UserInitiatedAction* userInitiatedAction() const { return m_userInitiatedAction.get(); } >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegate.h b/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegate.h >index 8ccfcc78b6427cd5009eeecbd7bbca7a68bde3bd..739bee1485a69b5659f1f433ee5c7853a3704339 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegate.h >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegate.h >@@ -57,6 +57,12 @@ typedef NS_ENUM(NSInteger, WKNavigationResponsePolicy) { > WKNavigationResponsePolicyAllow, > } WK_API_AVAILABLE(macosx(10.10), ios(8.0)); > >+typedef NS_ENUM(NSInteger, WKSafeBrowsingResultPolicy) { >+ WKSafeBrowsingResultPolicyCancel, >+ WKSafeBrowsingResultPolicyCancelAndShowWarning, >+ WKSafeBrowsingResultPolicyAllow, >+} WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA)); >+ > /*! A class conforming to the WKNavigationDelegate protocol can provide > methods for tracking progress for main frame navigations and for deciding > policy for main frame and subframe navigations. >@@ -86,6 +92,16 @@ typedef NS_ENUM(NSInteger, WKNavigationResponsePolicy) { > */ > - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler; > >+/*! @abstract Decides whether to allow or cancel a navigation that has failed a SafeBrowsing check. >+ @param webView The web view invoking the delegate method. >+ @param navigationAction Descriptive information about the action >+ triggering the navigation request. >+ @param decisionHandler The decision handler to call to allow or cancel the >+ navigation. The argument is one of the constants of the enumerated type WKSafeBrowsingResultPolicy. >+ @discussion If you do not implement this method, the web view will cancel the navigation and display a warning page. >+*/ >+- (void)webView:(WKWebView*)webView decidePolicyForSafeBrowsingResultForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKSafeBrowsingResultPolicy))decisionHandler; >+ > /*! @abstract Invoked when a main frame navigation starts. > @param webView The web view invoking the delegate method. > @param navigation The navigation. >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.h b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.h >index e35b7192c0b666ebff50f46f605c630a129db931..51334e7158526eb51d282b91811f91b7f923b598 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.h >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.h >@@ -53,6 +53,12 @@ WK_CLASS_AVAILABLE(macosx(10.10), ios(8.0)) > */ > @property (nonatomic) BOOL javaScriptCanOpenWindowsAutomatically; > >+/*! @abstract A Boolean value indicating whether the WKWebView should perform SafeBrowsing checks >+ before navigating to a URL. >+ @discussion The default value is NO. >+ */ >+@property (nonatomic) BOOL safeBrowsingEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA)); >+ > #if !TARGET_OS_IPHONE > /*! @abstract A Boolean value indicating whether Java is enabled. > @discussion The default value is NO. >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm >index 5fc0bc5a73af08d6188b1618cae1c79f5eddf42f..b3286d21a2ead2744ba1724b6da4632fa1b0a307 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm >@@ -68,6 +68,7 @@ - (void)encodeWithCoder:(NSCoder *)coder > [coder encodeDouble:self.minimumFontSize forKey:@"minimumFontSize"]; > [coder encodeBool:self.javaScriptEnabled forKey:@"javaScriptEnabled"]; > [coder encodeBool:self.javaScriptCanOpenWindowsAutomatically forKey:@"javaScriptCanOpenWindowsAutomatically"]; >+ [coder encodeBool:self.safeBrowsingEnabled forKey:@"safeBrowsingEnabled"]; > > #if PLATFORM(MAC) > [coder encodeBool:self.javaEnabled forKey:@"javaEnabled"]; >@@ -84,6 +85,7 @@ - (instancetype)initWithCoder:(NSCoder *)coder > self.minimumFontSize = [coder decodeDoubleForKey:@"minimumFontSize"]; > self.javaScriptEnabled = [coder decodeBoolForKey:@"javaScriptEnabled"]; > self.javaScriptCanOpenWindowsAutomatically = [coder decodeBoolForKey:@"javaScriptCanOpenWindowsAutomatically"]; >+ self.safeBrowsingEnabled = [coder decodeBoolForKey:@"safeBrowsingEnabled"]; > > #if PLATFORM(MAC) > self.javaEnabled = [coder decodeBoolForKey:@"javaEnabled"]; >@@ -139,6 +141,16 @@ - (void)_setStorageAccessPromptsEnabled:(BOOL)enabled > _preferences->setStorageAccessPromptsEnabled(enabled); > } > >+- (BOOL)safeBrowsingEnabled >+{ >+ return _preferences->safeBrowsingEnabled(); >+} >+ >+- (void)setSafeBrowsingEnabled:(BOOL)safeBrowsingEnabled >+{ >+ _preferences->setSafeBrowsingEnabled(safeBrowsingEnabled); >+} >+ > #pragma mark OS X-specific methods > > #if PLATFORM(MAC) >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >index 162db6ac3126f7919c99924edda3c0ee4f739b5e..f1999c558226d60f12f12cec9fc7791794ff048b 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >@@ -46,6 +46,7 @@ > #import "RemoteLayerTreeTransaction.h" > #import "RemoteObjectRegistry.h" > #import "RemoteObjectRegistryMessages.h" >+#import "SafeBrowsingContextProvider.h" > #import "UIDelegate.h" > #import "UserMediaProcessManager.h" > #import "VersionChecks.h" >@@ -6419,6 +6420,11 @@ - (void)_setDefersLoadingForTesting:(BOOL)defersLoading > _page->setDefersLoadingForTesting(defersLoading); > } > >+- (void)_setUseTestSafeBrowsingContext:(BOOL)useTestSafeBrowsingContext >+{ >+ WebKit::SafeBrowsingContextProvider::setUseTestContext(useTestSafeBrowsingContext); >+} >+ > - (void)_denyNextUserMediaRequest > { > #if ENABLE(MEDIA_STREAM) >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h >index 18ac6b861665b4716350cd2d979d41cd006e2b6e..e1fc075c8bf99518f9931d850bee8ac2a9d59d09 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h >@@ -463,6 +463,7 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) { > - (BOOL)_beginBackSwipeForTesting; > - (BOOL)_completeBackSwipeForTesting; > - (void)_setDefersLoadingForTesting:(BOOL)defersLoading; >+- (void)_setUseTestSafeBrowsingContext:(BOOL)useTestSafeBrowsingContext; > > @end > >diff --git a/Source/WebKit/UIProcess/Cocoa/NavigationState.h b/Source/WebKit/UIProcess/Cocoa/NavigationState.h >index 2bfe65c8beb1130cc5300ab6e252998fe3d1eb03..4202f9f4979790394ccda1c95c0b9b60520cb395 100644 >--- a/Source/WebKit/UIProcess/Cocoa/NavigationState.h >+++ b/Source/WebKit/UIProcess/Cocoa/NavigationState.h >@@ -34,6 +34,7 @@ > #import "PageLoadState.h" > #import "ProcessTerminationReason.h" > #import "ProcessThrottler.h" >+#import "WKNavigationDelegatePrivate.h" > #import <wtf/RetainPtr.h> > #import <wtf/RunLoop.h> > #import <wtf/WeakObjCPtr.h> >@@ -52,6 +53,7 @@ struct SecurityOriginData; > > namespace WebKit { > >+class SafeBrowsingController; > struct WebNavigationDataStore; > > class NavigationState final : private PageLoadState::Observer { >@@ -137,6 +139,8 @@ private: > void decidePolicyForNavigationAction(WebPageProxy&, Ref<API::NavigationAction>&&, Ref<WebFramePolicyListenerProxy>&&, API::Object* userData) override; > void decidePolicyForNavigationResponse(WebPageProxy&, Ref<API::NavigationResponse>&&, Ref<WebFramePolicyListenerProxy>&&, API::Object* userData) override; > >+ void decidePolicyForNavigationActionInternal(WebPageProxy&, Ref<API::NavigationAction>&&, WTF::Function<void(WKNavigationActionPolicy, std::optional<WebsitePoliciesData>&&)>&& completionHandler, API::Object* userData); >+ > NavigationState& m_navigationState; > }; > >@@ -182,6 +186,7 @@ private: > > WKWebView *m_webView; > WeakObjCPtr<id <WKNavigationDelegate> > m_navigationDelegate; >+ std::unique_ptr<SafeBrowsingController> m_safeBrowsingController; > > struct { > bool webViewDecidePolicyForNavigationActionDecisionHandler : 1; >diff --git a/Source/WebKit/UIProcess/Cocoa/NavigationState.mm b/Source/WebKit/UIProcess/Cocoa/NavigationState.mm >index 6f07ee13b6dc4e349be557f7bcd1bea1b2d84987..70dce64b3207d9e6d9d97ded5d5966e5452ea907 100644 >--- a/Source/WebKit/UIProcess/Cocoa/NavigationState.mm >+++ b/Source/WebKit/UIProcess/Cocoa/NavigationState.mm >@@ -39,6 +39,7 @@ > #import "Logging.h" > #import "NavigationActionData.h" > #import "PageLoadState.h" >+#import "SafeBrowsingController.h" > #import "WKBackForwardListInternal.h" > #import "WKBackForwardListItemInternal.h" > #import "WKFrameInfoInternal.h" >@@ -105,6 +106,7 @@ NavigationState::NavigationState(WKWebView *webView) > > navigationStates().add(m_webView->_page.get(), this); > m_webView->_page->pageLoadState().addObserver(*this); >+ m_safeBrowsingController = std::make_unique<SafeBrowsingController>(webView); > } > > NavigationState::~NavigationState() >@@ -478,29 +480,37 @@ static void tryAppLink(Ref<API::NavigationAction>&& navigationAction, const Stri > void NavigationState::NavigationClient::decidePolicyForNavigationAction(WebPageProxy& webPageProxy, Ref<API::NavigationAction>&& navigationAction, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userInfo) > { > ASSERT(webPageProxy.mainFrame()); >+ auto policyDecider = [&webPageProxy, navigationAction = navigationAction.copyRef(), userInfo, this] (WTF::Function<void(WKNavigationActionPolicy, std::optional<WebsitePoliciesData>&&)>&& completionHandler) mutable { >+ decidePolicyForNavigationActionInternal(webPageProxy, WTFMove(navigationAction), WTFMove(completionHandler), userInfo); >+ }; >+ m_navigationState.m_safeBrowsingController->checkURL(WTFMove(navigationAction), WTFMove(policyDecider), WTFMove(listener)); >+} >+ >+void NavigationState::NavigationClient::decidePolicyForNavigationActionInternal(WebPageProxy& webPageProxy, Ref<API::NavigationAction>&& navigationAction, WTF::Function<void(WKNavigationActionPolicy, std::optional<WebsitePoliciesData>&&)>&& completionHandler, API::Object* userInfo) >+{ > String mainFrameURLString = webPageProxy.mainFrame()->url(); > bool subframeNavigation = navigationAction->targetFrame() && !navigationAction->targetFrame()->isMainFrame(); > > if (!m_navigationState.m_navigationDelegateMethods.webViewDecidePolicyForNavigationActionDecisionHandler > && !m_navigationState.m_navigationDelegateMethods.webViewDecidePolicyForNavigationActionDecisionHandlerWebsitePolicies > && !m_navigationState.m_navigationDelegateMethods.webViewDecidePolicyForNavigationActionUserInfoDecisionHandlerWebsitePolicies) { >- auto completionHandler = [webPage = makeRef(webPageProxy), listener = WTFMove(listener), navigationAction = navigationAction.copyRef()] (bool followedLinkToApp) { >+ auto localCompletionHandler = [webPage = makeRef(webPageProxy), completionHandler = WTFMove(completionHandler), navigationAction = navigationAction.copyRef()] (bool followedLinkToApp) { > if (followedLinkToApp) { >- listener->ignore(); >+ completionHandler(WKNavigationActionPolicyCancel, std::nullopt); > return; > } > > if (!navigationAction->targetFrame()) { >- listener->use(std::nullopt); >+ completionHandler(WKNavigationActionPolicyAllow, std::nullopt); > return; > } > > RetainPtr<NSURLRequest> nsURLRequest = adoptNS(wrapper(API::URLRequest::create(navigationAction->request()).leakRef())); > if ([NSURLConnection canHandleRequest:nsURLRequest.get()] || webPage->urlSchemeHandlerForScheme([nsURLRequest URL].scheme)) { > if (navigationAction->shouldPerformDownload()) >- listener->download(); >+ completionHandler(_WKNavigationActionPolicyDownload, std::nullopt); > else >- listener->use(std::nullopt); >+ completionHandler(WKNavigationActionPolicyAllow, std::nullopt); > return; > } > >@@ -510,9 +520,9 @@ void NavigationState::NavigationClient::decidePolicyForNavigationAction(WebPageP > if (![[nsURLRequest URL] isFileURL]) > [[NSWorkspace sharedWorkspace] openURL:[nsURLRequest URL]]; > #endif >- listener->ignore(); >+ completionHandler(WKNavigationActionPolicyCancel, std::nullopt); > }; >- tryAppLink(WTFMove(navigationAction), mainFrameURLString, WTFMove(completionHandler)); >+ tryAppLink(WTFMove(navigationAction), mainFrameURLString, WTFMove(localCompletionHandler)); > return; > } > >@@ -524,7 +534,7 @@ void NavigationState::NavigationClient::decidePolicyForNavigationAction(WebPageP > > auto checker = CompletionHandlerCallChecker::create(navigationDelegate.get(), delegateHasWebsitePolicies ? @selector(_webView:decidePolicyForNavigationAction:decisionHandler:) : @selector(webView:decidePolicyForNavigationAction:decisionHandler:)); > >- auto decisionHandlerWithPolicies = [localListener = WTFMove(listener), navigationAction = navigationAction.copyRef(), checker = WTFMove(checker), mainFrameURLString, webPageProxy = makeRef(webPageProxy), subframeNavigation](WKNavigationActionPolicy actionPolicy, _WKWebsitePolicies *websitePolicies) mutable { >+ auto decisionHandlerWithPolicies = [localCompletionHandler = WTFMove(completionHandler), navigationAction = navigationAction.copyRef(), checker = WTFMove(checker), mainFrameURLString, webPageProxy = makeRef(webPageProxy), subframeNavigation](WKNavigationActionPolicy actionPolicy, _WKWebsitePolicies *websitePolicies) mutable { > if (checker->completionHandlerHasBeenCalled()) > return; > checker->didCallCompletionHandler(); >@@ -545,30 +555,30 @@ void NavigationState::NavigationClient::decidePolicyForNavigationAction(WebPageP > > switch (actionPolicy) { > case WKNavigationActionPolicyAllow: >- tryAppLink(WTFMove(navigationAction), mainFrameURLString, [localListener = WTFMove(localListener), data = WTFMove(data)](bool followedLinkToApp) mutable { >+ tryAppLink(WTFMove(navigationAction), mainFrameURLString, [localCompletionHandler = WTFMove(localCompletionHandler), data = WTFMove(data)](bool followedLinkToApp) mutable { > if (followedLinkToApp) { >- localListener->ignore(); >+ localCompletionHandler(WKNavigationActionPolicyCancel, std::nullopt); > return; > } > >- localListener->use(WTFMove(data)); >+ localCompletionHandler(WKNavigationActionPolicyAllow, WTFMove(data)); > }); > > break; > > case WKNavigationActionPolicyCancel: >- localListener->ignore(); >+ localCompletionHandler(WKNavigationActionPolicyCancel, std::nullopt); > break; > > // FIXME: Once we have a new enough compiler everywhere we don't need to ignore -Wswitch. > #pragma clang diagnostic push > #pragma clang diagnostic ignored "-Wswitch" > case _WKNavigationActionPolicyDownload: >- localListener->download(); >+ localCompletionHandler(_WKNavigationActionPolicyDownload, std::nullopt); > break; > case _WKNavigationActionPolicyAllowWithoutTryingAppLink: > #pragma clang diagnostic pop >- localListener->use(WTFMove(data)); >+ localCompletionHandler(WKNavigationActionPolicyAllow, WTFMove(data)); > break; > } > }; >diff --git a/Source/WebKit/UIProcess/Cocoa/SafeBrowsingContextProvider.h b/Source/WebKit/UIProcess/Cocoa/SafeBrowsingContextProvider.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3ebb78a1c75e491c2cc2ce6351a7fec0fa28b1e4 >--- /dev/null >+++ b/Source/WebKit/UIProcess/Cocoa/SafeBrowsingContextProvider.h >@@ -0,0 +1,48 @@ >+/* >+ * Copyright (C) 2018 Google LLC. 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. >+ */ >+ >+#pragma once >+ >+#import "WKFoundation.h" >+ >+#if WK_API_ENABLED >+ >+@class SSBLookupContext; >+ >+namespace WebKit { >+ >+class SafeBrowsingContextProvider { >+public: >+ static SSBLookupContext* sharedLookupContext(); >+ >+ static void setUseTestContext(bool useTestContext) { s_useTestContext = useTestContext; } >+ >+private: >+ static bool s_useTestContext; >+}; >+ >+} // namespace WebKit >+ >+#endif // WK_API_ENABLED >diff --git a/Source/WebKit/UIProcess/Cocoa/SafeBrowsingContextProvider.mm b/Source/WebKit/UIProcess/Cocoa/SafeBrowsingContextProvider.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..f77e28c7bcb1a877f21654fbf815d5ec3a0c41ce >--- /dev/null >+++ b/Source/WebKit/UIProcess/Cocoa/SafeBrowsingContextProvider.mm >@@ -0,0 +1,85 @@ >+/* >+ * Copyright (C) 2018 Google LLC. 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" >+#import "SafeBrowsingContextProvider.h" >+ >+#if WK_API_ENABLED >+ >+#import "SafeBrowsingSPI.h" >+ >+@interface _WKSafeBrowsingTestServiceLookupResult : SSBServiceLookupResult >+@property (nonatomic, readwrite, getter=isPhishing) BOOL phishing; >+@end >+ >+@implementation _WKSafeBrowsingTestServiceLookupResult >+@synthesize phishing=_phishing; >+@end >+ >+@interface _WKSafeBrowsingTestLookupContext : SSBLookupContext >++ (_WKSafeBrowsingTestLookupContext *)sharedLookupContext; >+- (void)lookUpURL:(NSURL *)URL completionHandler:(void (^)(SSBLookupResult *, NSError *))completionHandler; >+@end >+ >+@implementation _WKSafeBrowsingTestLookupContext >+ >++ (_WKSafeBrowsingTestLookupContext*) sharedLookupContext >+{ >+ static _WKSafeBrowsingTestLookupContext* sharedTestLookupContext; >+ static dispatch_once_t onceToken; >+ dispatch_once(&onceToken, ^{ >+ sharedTestLookupContext = [[self alloc] init]; >+ }); >+ >+ return sharedTestLookupContext; >+} >+ >+- (void)lookUpURL:(NSURL *)URL completionHandler:(void (^)(SSBLookupResult *, NSError *))completionHandler >+{ >+ SSBLookupResult* lookupResult = [[SSBLookupResult alloc] init]; >+ _WKSafeBrowsingTestServiceLookupResult* result = [[_WKSafeBrowsingTestServiceLookupResult alloc] init]; >+ if ([[URL absoluteString] isEqualToString:@"sb://host/phishing.html"]) >+ [result setPhishing:YES]; >+ NSArray<SSBServiceLookupResult *> *serviceLookupResults = [NSArray arrayWithObject:[result autorelease]]; >+ [lookupResult setValue:serviceLookupResults forKey:@"serviceLookupResults"]; >+ completionHandler([lookupResult autorelease], nil); >+} >+ >+@end >+ >+namespace WebKit { >+ >+bool SafeBrowsingContextProvider::s_useTestContext = false; >+ >+SSBLookupContext* SafeBrowsingContextProvider::sharedLookupContext() >+{ >+ if (s_useTestContext) >+ return [_WKSafeBrowsingTestLookupContext sharedLookupContext]; >+ return [SSBLookupContext sharedLookupContext]; >+} >+ >+} // namespace WebKit >+ >+#endif // WK_API_ENABLED >diff --git a/Source/WebKit/UIProcess/Cocoa/SafeBrowsingController.h b/Source/WebKit/UIProcess/Cocoa/SafeBrowsingController.h >new file mode 100644 >index 0000000000000000000000000000000000000000..ff53a5d60c8fbba7739d6d9e7b7af0478441b63c >--- /dev/null >+++ b/Source/WebKit/UIProcess/Cocoa/SafeBrowsingController.h >@@ -0,0 +1,92 @@ >+/* >+ * Copyright (C) 2018 Google LLC. 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. >+ */ >+ >+#pragma once >+ >+#import "WKFoundation.h" >+ >+#if WK_API_ENABLED >+ >+#import "WKNavigationDelegatePrivate.h" >+#import "WebsitePoliciesData.h" >+#import <WebCore/URL.h> >+#import <WebCore/URLHash.h> >+#import <wtf/HashSet.h> >+#import <wtf/WeakPtr.h> >+ >+@class WKWebView; >+ >+namespace API { >+class NavigationAction; >+} >+ >+namespace WebKit { >+ >+class WebFramePolicyListenerProxy; >+ >+class SafeBrowsingController { >+public: >+ explicit SafeBrowsingController(WKWebView *); >+ ~SafeBrowsingController(); >+ >+ using NavigationPolicyDecider = WTF::Function<void(WTF::Function<void(WKNavigationActionPolicy, std::optional<WebsitePoliciesData>&&)>&&)>; >+ >+ void checkURL(Ref<API::NavigationAction>&&, NavigationPolicyDecider&&, Ref<WebFramePolicyListenerProxy>&&); >+ >+private: >+ enum class SafeBrowsingResult { Safe, Unsafe }; >+ struct SafeBrowsingCheck { >+ SafeBrowsingCheck(Ref<WebFramePolicyListenerProxy>&& listener, Ref<API::NavigationAction>&& navigationAction) >+ : listener(WTFMove(listener)) >+ , navigationAction(WTFMove(navigationAction)) >+ { >+ } >+ >+ std::optional<WKNavigationActionPolicy> navigationPolicyDecision; >+ std::optional<WebsitePoliciesData> websitePoliciesData; >+ std::optional<SafeBrowsingResult> safeBrowsingResult; >+ Ref<WebFramePolicyListenerProxy> listener; >+ Ref<API::NavigationAction> navigationAction; >+ }; >+ >+ void receivedNavigationPolicyDecision(SafeBrowsingCheck&, WKNavigationActionPolicy, std::optional<WebsitePoliciesData>&&); >+ >+ // Takes a |SafeBrowsingCheck*| rather than |SafeBrowsingCheck&| since the >+ // check might have already been destroyed, e.g., if the embedder's navigation >+ // policy response was to ignore the navigation. >+ void receivedSafeBrowsingResult(SafeBrowsingCheck*, SafeBrowsingResult); >+ >+ void maybeFinishedCheck(SafeBrowsingCheck&); >+ >+ WKWebView *m_webView; >+ HashSet<std::unique_ptr<SafeBrowsingCheck>> m_checks; >+ HashSet<WebCore::URL> m_warningIgnoredUrls; >+ WeakPtrFactory<SafeBrowsingController> m_weakPtrFactory; >+ static const char* s_warningPageUrl; >+}; >+ >+} // namespace WebKit >+ >+#endif // WK_API_ENABLED >diff --git a/Source/WebKit/UIProcess/Cocoa/SafeBrowsingController.mm b/Source/WebKit/UIProcess/Cocoa/SafeBrowsingController.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..974702278c3300539df7d023dbea5dbb1a061a80 >--- /dev/null >+++ b/Source/WebKit/UIProcess/Cocoa/SafeBrowsingController.mm >@@ -0,0 +1,199 @@ >+/* >+ * Copyright (C) 2018 Google LLC. 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" >+#import "SafeBrowsingController.h" >+ >+#if WK_API_ENABLED >+ >+#import "APINavigationAction.h" >+#import "SafeBrowsingContextProvider.h" >+#import "SafeBrowsingSPI.h" >+#import "WKNavigationActionInternal.h" >+#import "WKPreferences.h" >+#import "WKWebViewConfiguration.h" >+#import "WKWebViewInternal.h" >+#import "WebFramePolicyListenerProxy.h" >+#import "WebPageProxy.h" >+ >+namespace WebKit { >+ >+const char* SafeBrowsingController::s_warningPageUrl = "file:///SafeBrowsing"; >+ >+SafeBrowsingController::SafeBrowsingController(WKWebView *webView) >+ : m_webView(webView) >+{ >+} >+ >+SafeBrowsingController::~SafeBrowsingController() >+{ >+} >+ >+void SafeBrowsingController::checkURL(Ref<API::NavigationAction>&& navigationAction, NavigationPolicyDecider&& policyDecider, Ref<WebFramePolicyListenerProxy>&& listener) >+{ >+ bool shouldSkipSafeBrowsingLookUp = !m_webView.configuration.preferences.safeBrowsingEnabled; >+ if (!shouldSkipSafeBrowsingLookUp) { >+ bool warningBypassed = navigationAction->navigationType() == WebCore::NavigationType::LinkClicked >+ && navigationAction->sourceFrame() >+ && navigationAction->sourceFrame()->page()->pageLoadState().url() == s_warningPageUrl >+ && navigationAction->sourceFrame()->page()->currentURL() == navigationAction->originalURL().string(); >+ >+ // FIXME: Figure out the right persistence model. Right now, this persists ignoring warnings for the currently >+ // displayed URL (i.e., the main-frame URL), but not for the specific subframe that triggered the >+ // warning. So the next attempt at loading that subframe will still trigger the warning. >+ // For subframes, the user might have no idea what URL is 'dangerous', so persisting that URL seems >+ // questionable. >+ // Another approach would be to exempt all loads triggered by the main-frame URL once the user >+ // bypasses a warning with that main-frame URL. But then we also need to track what warning types >+ // the user has decided to bypass (e.g., maybe the user bypassed a phishing warning, but that >+ // shouldn't automatically imply they also want to bypass malware warnings). >+ if (warningBypassed) >+ m_warningIgnoredUrls.add(navigationAction->originalURL()); >+ >+ shouldSkipSafeBrowsingLookUp = warningBypassed || m_warningIgnoredUrls.contains(navigationAction->originalURL()); >+ } >+ >+ auto safeBrowsingCheck = std::make_unique<SafeBrowsingCheck>(WTFMove(listener), WTFMove(navigationAction)); >+ auto checkRaw = safeBrowsingCheck.get(); >+ m_checks.add(WTFMove(safeBrowsingCheck)); >+ >+ auto policyCompletionHandler = [checkRaw, weakThis = m_weakPtrFactory.createWeakPtr(*this)] (WKNavigationActionPolicy policy, std::optional<WebsitePoliciesData>&& data) mutable { >+ if (weakThis) >+ weakThis->receivedNavigationPolicyDecision(*checkRaw, policy, WTFMove(data)); >+ }; >+ >+ policyDecider(WTFMove(policyCompletionHandler)); >+ >+ if (shouldSkipSafeBrowsingLookUp) { >+ receivedSafeBrowsingResult(checkRaw, SafeBrowsingResult::Safe); >+ return; >+ } >+ >+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) >+ auto weakThis = m_weakPtrFactory.createWeakPtr(*this); >+ [SafeBrowsingContextProvider::sharedLookupContext() lookUpURL:checkRaw->navigationAction->request().url() completionHandler:^(SSBLookupResult* result, NSError* error) { >+ // FIXME: Remove logging. >+ if (error) >+ WTFLogAlways("Error doing SafeBrowsing check"); >+ if (!weakThis) >+ return; >+ SafeBrowsingResult safeBrowsingResult = SafeBrowsingResult::Safe; >+ if (result.serviceLookupResults) { >+ for (SSBServiceLookupResult* details in result.serviceLookupResults) { >+ // FIXME: Do we want to keep track of the different types in order to give >+ // different warnings? >+ if (details.isPhishing || details.isMalware || details.isUnwantedSoftware || details.isKnownToBeUnsafe) >+ safeBrowsingResult = SafeBrowsingResult::Unsafe; >+ } >+ } >+ weakThis->receivedSafeBrowsingResult(checkRaw, safeBrowsingResult); >+ }]; >+#else >+ receivedSafeBrowsingDecision(checkRaw, false); >+#endif >+} >+ >+void SafeBrowsingController::receivedNavigationPolicyDecision(SafeBrowsingController::SafeBrowsingCheck& check, WKNavigationActionPolicy policy, std::optional<WebsitePoliciesData>&& data) >+{ >+ check.navigationPolicyDecision = policy; >+ check.websitePoliciesData = WTFMove(data); >+ maybeFinishedCheck(check); >+} >+ >+void SafeBrowsingController::receivedSafeBrowsingResult(SafeBrowsingCheck* check, SafeBrowsingResult safeBrowsingResult) >+{ >+ if (!m_checks.contains(check)) >+ return; >+ >+ check->safeBrowsingResult = safeBrowsingResult; >+ maybeFinishedCheck(*check); >+} >+ >+void SafeBrowsingController::maybeFinishedCheck(SafeBrowsingController::SafeBrowsingCheck& check) >+{ >+ if (!check.navigationPolicyDecision) >+ return; >+ >+ if (check.navigationPolicyDecision.value() == WKNavigationActionPolicyAllow && !check.safeBrowsingResult) >+ return; >+ >+ switch (check.navigationPolicyDecision.value()) { >+ case WKNavigationActionPolicyAllow: { >+ if (check.safeBrowsingResult == SafeBrowsingResult::Safe) { >+ check.listener->use(WTFMove(check.websitePoliciesData)); >+ return; >+ } >+ >+ auto weakThis = m_weakPtrFactory.createWeakPtr(*this); >+ void (^safeBrowsingPolicyHandler)(WKSafeBrowsingResultPolicy) = ^(WKSafeBrowsingResultPolicy policy) { >+ if (!weakThis) >+ return; >+ switch (policy) { >+ case WKSafeBrowsingResultPolicyCancel: >+ check.listener->ignore(); >+ break; >+ case WKSafeBrowsingResultPolicyCancelAndShowWarning: { >+ check.listener->ignore(); >+ // FIXME: This really needs to be loaded in a way that permits localization. >+ // Possibly put strings in LocalizedStrings.cpp or LocalizedStringCocoa.mm. >+ // Make the warning message similar/identical to Safari, which means different >+ // wording depending on the type of warning (phishing, malware, etc.). >+ bool targetFrameIsMainFrame = check.navigationAction->targetFrame()->isMainFrame(); >+ auto targetMainFrameUrl = targetFrameIsMainFrame ? check.navigationAction->request().url() : WebCore::URL(WebCore::ParsedURLString, check.navigationAction->targetFrame()->page()->currentURL()); >+ NSString* warningString = [NSString stringWithFormat:@"<style>body { background-color: red; }</style><body><h1>This is a simple SafeBrowsing warning.</h1><h2>You've been warned!!!</h2><h2><a id='visitAnyway' href='%s'>Live dangerously and visit the site anyway</a></h2>", targetMainFrameUrl.string().utf8().data()]; >+ if (targetFrameIsMainFrame) >+ [m_webView _page]->loadAlternateHTMLString(warningString, WebCore::URL(WebCore::ParsedURLString, s_warningPageUrl), targetMainFrameUrl, nullptr, check.navigationAction->redirectedByClient(), check.navigationAction->navigationType(), check.navigationAction->targetBackForwardItemIdentifier()); >+ else >+ [m_webView _page]->loadAlternateHTMLString(warningString, WebCore::URL(WebCore::ParsedURLString, s_warningPageUrl), targetMainFrameUrl, nullptr, WebCore::RedirectedByClient::No, WebCore::NavigationType::Reload); >+ break; >+ } >+ case WKSafeBrowsingResultPolicyAllow: >+ check.listener->use(WTFMove(check.websitePoliciesData)); >+ break; >+ } >+ m_checks.remove(&check); >+ }; >+ auto navigationDelegate = [m_webView navigationDelegate]; >+ if (navigationDelegate && [navigationDelegate respondsToSelector:@selector(webView:decidePolicyForSafeBrowsingResultForNavigationAction:decisionHandler:)]) >+ [navigationDelegate webView:m_webView decidePolicyForSafeBrowsingResultForNavigationAction:wrapper(check.navigationAction) decisionHandler:safeBrowsingPolicyHandler]; >+ else >+ safeBrowsingPolicyHandler(WKSafeBrowsingResultPolicyCancelAndShowWarning); >+ return; >+ } >+ case WKNavigationActionPolicyCancel: >+ check.listener->ignore(); >+ break; >+ case _WKNavigationActionPolicyDownload: >+ check.listener->download(); >+ break; >+ default: >+ ASSERT_NOT_REACHED(); >+ } >+ m_checks.remove(&check); >+} >+ >+} // namespace WebKit >+ >+#endif // WK_API_ENABLED >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index 792b455e86b716469ac6b5902c94d441f8c6e401..f68aef5930f450346d7407b821985cdafcc3674d 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -1099,7 +1099,7 @@ RefPtr<API::Navigation> WebPageProxy::loadHTMLString(const String& htmlString, c > return WTFMove(navigation); > } > >-void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const WebCore::URL& baseURL, const WebCore::URL& unreachableURL, API::Object* userData) >+void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const WebCore::URL& baseURL, const WebCore::URL& unreachableURL, API::Object* userData, RedirectedByClient redirectedByClient, NavigationType navigationType, const std::optional<BackForwardItemIdentifier>& targetBackForwardItemIdentifier) > { > // When the UIProcess is in the process of handling a failing provisional load, do not attempt to > // start a second alternative HTML load as this will prevent the page load state from being >@@ -1121,13 +1121,18 @@ void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const WebCo > if (m_mainFrame) > m_mainFrame->setUnreachableURL(unreachableURL); > >+ auto navigation = m_navigationState->createLoadDataNavigation(); >+ > LoadParameters loadParameters; >- loadParameters.navigationID = 0; >+ loadParameters.navigationID = navigation->navigationID(); > loadParameters.string = htmlString; > loadParameters.baseURLString = baseURL; > loadParameters.unreachableURLString = unreachableURL; > loadParameters.provisionalLoadErrorURLString = m_failingProvisionalLoadURL; > loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get()); >+ loadParameters.redirectedByClient = redirectedByClient; >+ loadParameters.navigationType = navigationType; >+ loadParameters.targetBackForwardItemIdentifier = targetBackForwardItemIdentifier; > addPlatformLoadParameters(loadParameters); > > m_process->assumeReadAccessToBaseURL(baseURL); >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index 288a36d0d197e2419f4a930506c128f162cea56d..2b28d05e5d500194ad746dc4c131ddf13849a91f 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -442,7 +442,7 @@ public: > RefPtr<API::Navigation> loadFile(const String& fileURL, const String& resourceDirectoryURL, API::Object* userData = nullptr); > RefPtr<API::Navigation> loadData(API::Data*, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr); > RefPtr<API::Navigation> loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData = nullptr); >- void loadAlternateHTMLString(const String& htmlString, const WebCore::URL& baseURL, const WebCore::URL& unreachableURL, API::Object* userData = nullptr); >+ void loadAlternateHTMLString(const String& htmlString, const WebCore::URL& baseURL, const WebCore::URL& unreachableURL, API::Object* userData = nullptr, WebCore::RedirectedByClient = WebCore::RedirectedByClient::No, WebCore::NavigationType = WebCore::NavigationType::Other, const std::optional<WebCore::BackForwardItemIdentifier>& = std::optional<WebCore::BackForwardItemIdentifier>()); > void loadPlainTextString(const String&, API::Object* userData = nullptr); > void loadWebArchiveData(API::Data*, API::Object* userData = nullptr); > void navigateToPDFLinkWithSimulatedClick(const String& url, WebCore::IntPoint documentPoint, WebCore::IntPoint screenPoint); >diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >index d8d29516a6cb6445bbdc5de7497cee163f160645..c88192e6581a12e76a41538742954a0002566e35 100644 >--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj >+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >@@ -1308,6 +1308,10 @@ > 75A8D2C9187CCFAF00C39C9E /* WKWebsiteDataStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 75A8D2C5187CCF9F00C39C9E /* WKWebsiteDataStore.mm */; }; > 75A8D2D6187D1C0E00C39C9E /* WKWebsiteDataStoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 75A8D2D4187D1C0100C39C9E /* WKWebsiteDataStoreInternal.h */; }; > 762B748D120BC75C00819339 /* WKPreferencesRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 762B7484120BBA2D00819339 /* WKPreferencesRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 7727593E20CADA7F00D88206 /* SafeBrowsingContextProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 7727593D20CADA7F00D88206 /* SafeBrowsingContextProvider.h */; }; >+ 7727594020CADC0D00D88206 /* SafeBrowsingContextProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7727593F20CADC0D00D88206 /* SafeBrowsingContextProvider.mm */; }; >+ 7749087E208554C500072D86 /* SafeBrowsingController.h in Headers */ = {isa = PBXBuildFile; fileRef = 7749087D208554C500072D86 /* SafeBrowsingController.h */; }; >+ 774908822085562400072D86 /* SafeBrowsingController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 774908812085562400072D86 /* SafeBrowsingController.mm */; }; > 7A1E2A851EEFE8920037A0E0 /* APINotificationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A1E2A841EEFE88A0037A0E0 /* APINotificationProvider.h */; }; > 7A3ACE1B1EEEF79B00A864A4 /* APIInjectedBundlePageLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A3ACE1A1EEEF78C00A864A4 /* APIInjectedBundlePageLoaderClient.h */; }; > 7A772C8D1DDD4A25000F34F1 /* com.apple.WebKit.plugin-common.sb in Copy Plug-in Sandbox Profiles */ = {isa = PBXBuildFile; fileRef = 7A1506721DD56298001F4B58 /* com.apple.WebKit.plugin-common.sb */; }; >@@ -3782,6 +3786,10 @@ > 75A8D2D4187D1C0100C39C9E /* WKWebsiteDataStoreInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebsiteDataStoreInternal.h; sourceTree = "<group>"; }; > 762B7481120BBA0100819339 /* FontSmoothingLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontSmoothingLevel.h; sourceTree = "<group>"; }; > 762B7484120BBA2D00819339 /* WKPreferencesRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPreferencesRefPrivate.h; sourceTree = "<group>"; }; >+ 7727593D20CADA7F00D88206 /* SafeBrowsingContextProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SafeBrowsingContextProvider.h; sourceTree = "<group>"; }; >+ 7727593F20CADC0D00D88206 /* SafeBrowsingContextProvider.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SafeBrowsingContextProvider.mm; sourceTree = "<group>"; }; >+ 7749087D208554C500072D86 /* SafeBrowsingController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SafeBrowsingController.h; sourceTree = "<group>"; }; >+ 774908812085562400072D86 /* SafeBrowsingController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SafeBrowsingController.mm; sourceTree = "<group>"; }; > 7A1506721DD56298001F4B58 /* com.apple.WebKit.plugin-common.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "com.apple.WebKit.plugin-common.sb"; sourceTree = "<group>"; }; > 7A1E2A841EEFE88A0037A0E0 /* APINotificationProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APINotificationProvider.h; sourceTree = "<group>"; }; > 7A3ACE1A1EEEF78C00A864A4 /* APIInjectedBundlePageLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIInjectedBundlePageLoaderClient.h; sourceTree = "<group>"; }; >@@ -5536,6 +5544,10 @@ > CDA29A1E1CBEB5FB00901CCF /* PlaybackSessionManagerProxy.h */, > CDA29A221CBEB61A00901CCF /* PlaybackSessionManagerProxy.messages.in */, > CDA29A1F1CBEB5FB00901CCF /* PlaybackSessionManagerProxy.mm */, >+ 7727593D20CADA7F00D88206 /* SafeBrowsingContextProvider.h */, >+ 7727593F20CADC0D00D88206 /* SafeBrowsingContextProvider.mm */, >+ 7749087D208554C500072D86 /* SafeBrowsingController.h */, >+ 774908812085562400072D86 /* SafeBrowsingController.mm */, > 1A002D47196B345D00B9AD44 /* SessionStateCoding.h */, > 1A002D46196B345D00B9AD44 /* SessionStateCoding.mm */, > 3157135C2040A9B20084F9CF /* SystemPreviewControllerCocoa.mm */, >@@ -9193,6 +9205,8 @@ > 51E6C1641F2935DD00FD3437 /* ResourceLoadStatisticsPersistentStorage.h in Headers */, > 1A30066E1110F4F70031937C /* ResponsivenessTimer.h in Headers */, > 410482CE1DDD324F00F006D0 /* RTCNetwork.h in Headers */, >+ 7727593E20CADA7F00D88206 /* SafeBrowsingContextProvider.h in Headers */, >+ 7749087E208554C500072D86 /* SafeBrowsingController.h in Headers */, > 0E97D74D200E900400BF6643 /* SafeBrowsingSPI.h in Headers */, > BC2D021712AC41CB00E732A3 /* SameDocumentNavigationType.h in Headers */, > 1AAB4A8D1296F0A20023952F /* SandboxExtension.h in Headers */, >@@ -10358,13 +10372,9 @@ > buildActionMask = 2147483647; > files = ( > ); >- inputFileListPaths = ( >- ); > inputPaths = ( > ); > name = "Unlock keychain"; >- outputFileListPaths = ( >- ); > outputPaths = ( > ); > runOnlyForDeploymentPostprocessing = 0; >@@ -10376,13 +10386,9 @@ > buildActionMask = 2147483647; > files = ( > ); >- inputFileListPaths = ( >- ); > inputPaths = ( > ); > name = "Unlock keychain"; >- outputFileListPaths = ( >- ); > outputPaths = ( > ); > runOnlyForDeploymentPostprocessing = 0; >@@ -10394,13 +10400,9 @@ > buildActionMask = 2147483647; > files = ( > ); >- inputFileListPaths = ( >- ); > inputPaths = ( > ); > name = "Remove stale entitlement file"; >- outputFileListPaths = ( >- ); > outputPaths = ( > ); > runOnlyForDeploymentPostprocessing = 0; >@@ -10412,13 +10414,9 @@ > buildActionMask = 2147483647; > files = ( > ); >- inputFileListPaths = ( >- ); > inputPaths = ( > ); > name = "Remove stale entitlement file"; >- outputFileListPaths = ( >- ); > outputPaths = ( > ); > runOnlyForDeploymentPostprocessing = 0; >@@ -10430,14 +10428,10 @@ > buildActionMask = 2147483647; > files = ( > ); >- inputFileListPaths = ( >- ); > inputPaths = ( > "$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent", > ); > name = "Process WebContent entitlements"; >- outputFileListPaths = ( >- ); > outputPaths = ( > ); > runOnlyForDeploymentPostprocessing = 0; >@@ -10449,14 +10443,10 @@ > buildActionMask = 2147483647; > files = ( > ); >- inputFileListPaths = ( >- ); > inputPaths = ( > "$(TEMP_FILE_DIR)/$(FULL_PRODUCT_NAME).xcent", > ); > name = "Process WebContent entitlements"; >- outputFileListPaths = ( >- ); > outputPaths = ( > ); > runOnlyForDeploymentPostprocessing = 0; >@@ -10993,6 +10983,8 @@ > BC111B09112F5E3C00337BAB /* ResponsivenessTimer.cpp in Sources */, > 410482CD1DDD324C00F006D0 /* RTCNetwork.cpp in Sources */, > 41B28B0A1F83AD4200FB52AC /* RTCPacketOptions.cpp in Sources */, >+ 7727594020CADC0D00D88206 /* SafeBrowsingContextProvider.mm in Sources */, >+ 774908822085562400072D86 /* SafeBrowsingController.mm in Sources */, > 1AAB4AAA1296F1540023952F /* SandboxExtensionMac.mm in Sources */, > E1E552C416AE065F004ED653 /* SandboxInitialiationParametersMac.mm in Sources */, > E19BDA8B19368D4600B97F57 /* SandboxUtilities.mm in Sources */, >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >index e9fc74da4ebec46856176eb071a75de6eb577cf3..5a7359fe2e12346bead591448dce26509d292ebe 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >@@ -813,7 +813,7 @@ void WebFrameLoaderClient::applyToDocumentLoader(WebsitePoliciesData&& websitePo > WebsitePoliciesData::applyToDocumentLoader(WTFMove(websitePolicies), *documentLoader); > } > >-void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, bool didReceiveRedirectResponse, FormState* formState, PolicyDecisionMode policyDecisionMode, FramePolicyFunction&& function) >+void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, bool didReceiveRedirectResponse, RedirectedByClient redirectedByClient, FormState* formState, PolicyDecisionMode policyDecisionMode, FramePolicyFunction&& function) > { > WebPage* webPage = m_frame ? m_frame->page() : nullptr; > if (!webPage) { >@@ -865,6 +865,7 @@ void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const Navigat > navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy(); > navigationActionData.downloadAttribute = navigationAction.downloadAttribute(); > navigationActionData.isRedirect = didReceiveRedirectResponse; >+ navigationActionData.redirectedByClient = redirectedByClient; > navigationActionData.treatAsSameOriginNavigation = navigationAction.treatAsSameOriginNavigation(); > navigationActionData.isCrossOriginWindowOpenNavigation = navigationAction.isCrossOriginWindowOpenNavigation(); > navigationActionData.opener = navigationAction.opener(); >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h >index 1f92701c3bbe30e10f39a6a34785ad4615f0c9de..be8551dcaaec4c815d29bcb07b18b75132cf540b 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h >@@ -125,7 +125,7 @@ private: > > void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::FramePolicyFunction&&) final; > void dispatchDecidePolicyForNewWindowAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, const String& frameName, WebCore::FramePolicyFunction&&) final; >- void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, bool didReceiveRedirectResponse, WebCore::FormState*, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&) final; >+ void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, bool didReceiveRedirectResponse, WebCore::RedirectedByClient, WebCore::FormState*, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&) final; > void cancelPolicyCheck() final; > > void dispatchUnableToImplementPolicy(const WebCore::ResourceError&) final; >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >index af6dc65af0454667c90c658830f77645d2f1e40c..a136d87f3422fd598adb51b91d7e24930233918e 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >@@ -1275,7 +1275,7 @@ void WebPage::loadRequest(LoadParameters&& loadParameters) > ASSERT(!m_pendingNavigationID); > } > >-void WebPage::loadDataImpl(uint64_t navigationID, Ref<SharedBuffer>&& sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData) >+void WebPage::loadDataImpl(uint64_t navigationID, Ref<SharedBuffer>&& sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData, RedirectedByClient redirectedByClient, NavigationType navigationType, const std::optional<BackForwardItemIdentifier>& targetBackForwardItemIdentifier) > { > SendStopResponsivenessTimer stopper; > >@@ -1290,17 +1290,19 @@ void WebPage::loadDataImpl(uint64_t navigationID, Ref<SharedBuffer>&& sharedBuff > m_loaderClient->willLoadDataRequest(*this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), WebProcess::singleton().transformHandlesToObjects(userData.object()).get()); > > // Initate the load in WebCore. >- m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(*m_mainFrame->coreFrame(), request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData)); >+ LockBackForwardList lockBackForwardList = redirectedByClient == RedirectedByClient::Yes ? LockBackForwardList::Yes : LockBackForwardList::No; >+ HistoryItem* targetItem = targetBackForwardItemIdentifier ? WebBackForwardListProxy::itemForID(*targetBackForwardItemIdentifier) : nullptr; >+ m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(*m_mainFrame->coreFrame(), request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData, lockBackForwardList, navigationType, targetItem)); > } > >-void WebPage::loadStringImpl(uint64_t navigationID, const String& htmlString, const String& MIMEType, const URL& baseURL, const URL& unreachableURL, const UserData& userData) >+void WebPage::loadStringImpl(uint64_t navigationID, const String& htmlString, const String& MIMEType, const URL& baseURL, const URL& unreachableURL, const UserData& userData, RedirectedByClient redirectedByClient, NavigationType navigationType, const std::optional<BackForwardItemIdentifier>& targetBackForwardItemIdentifier) > { > if (!htmlString.isNull() && htmlString.is8Bit()) { > auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters8()), htmlString.length() * sizeof(LChar)); >- loadDataImpl(navigationID, WTFMove(sharedBuffer), MIMEType, ASCIILiteral("latin1"), baseURL, unreachableURL, userData); >+ loadDataImpl(navigationID, WTFMove(sharedBuffer), MIMEType, ASCIILiteral("latin1"), baseURL, unreachableURL, userData, redirectedByClient, navigationType, targetBackForwardItemIdentifier); > } else { > auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters16()), htmlString.length() * sizeof(UChar)); >- loadDataImpl(navigationID, WTFMove(sharedBuffer), MIMEType, ASCIILiteral("utf-16"), baseURL, unreachableURL, userData); >+ loadDataImpl(navigationID, WTFMove(sharedBuffer), MIMEType, ASCIILiteral("utf-16"), baseURL, unreachableURL, userData, redirectedByClient, navigationType, targetBackForwardItemIdentifier); > } > } > >@@ -1329,7 +1331,7 @@ void WebPage::loadAlternateHTMLString(const LoadParameters& loadParameters) > URL unreachableURL = loadParameters.unreachableURLString.isEmpty() ? URL() : URL(URL(), loadParameters.unreachableURLString); > URL provisionalLoadErrorURL = loadParameters.provisionalLoadErrorURLString.isEmpty() ? URL() : URL(URL(), loadParameters.provisionalLoadErrorURLString); > m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL); >- loadStringImpl(0, loadParameters.string, ASCIILiteral("text/html"), baseURL, unreachableURL, loadParameters.userData); >+ loadStringImpl(loadParameters.navigationID, loadParameters.string, ASCIILiteral("text/html"), baseURL, unreachableURL, loadParameters.userData, loadParameters.redirectedByClient, loadParameters.navigationType, loadParameters.targetBackForwardItemIdentifier); > m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ }); > } > >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h >index 63485fc8e7f1e347916c8a5e5741dbc33e0c1b1c..c8f6d16967872dcbe9df1561b1ac5e447de8031a 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.h >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.h >@@ -49,6 +49,7 @@ > #include "WebURLSchemeHandler.h" > #include "WebUserContentController.h" > #include <WebCore/ActivityState.h> >+#include <WebCore/BackForwardItemIdentifier.h> > #include <WebCore/DictionaryPopupInfo.h> > #include <WebCore/DisabledAdaptations.h> > #include <WebCore/FrameLoaderTypes.h> >@@ -1148,8 +1149,8 @@ private: > > String sourceForFrame(WebFrame*); > >- void loadDataImpl(uint64_t navigationID, Ref<WebCore::SharedBuffer>&&, const String& MIMEType, const String& encodingName, const WebCore::URL& baseURL, const WebCore::URL& failingURL, const UserData&); >- void loadStringImpl(uint64_t navigationID, const String&, const String& MIMEType, const WebCore::URL& baseURL, const WebCore::URL& failingURL, const UserData&); >+ void loadDataImpl(uint64_t navigationID, Ref<WebCore::SharedBuffer>&&, const String& MIMEType, const String& encodingName, const WebCore::URL& baseURL, const WebCore::URL& failingURL, const UserData&, WebCore::RedirectedByClient = WebCore::RedirectedByClient::No, WebCore::NavigationType = WebCore::NavigationType::Other, const std::optional<WebCore::BackForwardItemIdentifier>& targetBackForwardItemIdentifier = std::optional<WebCore::BackForwardItemIdentifier>()); >+ void loadStringImpl(uint64_t navigationID, const String&, const String& MIMEType, const WebCore::URL& baseURL, const WebCore::URL& failingURL, const UserData&, WebCore::RedirectedByClient = WebCore::RedirectedByClient::No, WebCore::NavigationType = WebCore::NavigationType::Other, const std::optional<WebCore::BackForwardItemIdentifier>& targetBackForwardItemIdentifier = std::optional<WebCore::BackForwardItemIdentifier>()); > > // Actions > void tryClose(); >diff --git a/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h b/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h >index 0d6aaf87af320b8126fd440f041986be5c82334c..4d195ffb51487c800f3f56076ed3844011e7dc8d 100644 >--- a/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h >+++ b/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h >@@ -128,7 +128,7 @@ private: > > void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::FramePolicyFunction&&) final; > void dispatchDecidePolicyForNewWindowAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, const WTF::String& frameName, WebCore::FramePolicyFunction&&) final; >- void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, bool didReceiveRedirectResponse, WebCore::FormState*, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&) final; >+ void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, bool didReceiveRedirectResponse, WebCore::RedirectedByClient, WebCore::FormState*, WebCore::PolicyDecisionMode, WebCore::FramePolicyFunction&&) final; > void cancelPolicyCheck() final; > > void dispatchUnableToImplementPolicy(const WebCore::ResourceError&) final; >diff --git a/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm b/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm >index e59c18991c7f4459f209c2240245669ef712497d..b7ccb91f378c58f8360d16f787357cec66d20abd 100644 >--- a/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm >+++ b/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm >@@ -901,7 +901,7 @@ void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const Navigati > decisionListener:setUpPolicyListener(WTFMove(function), PolicyAction::Ignore, tryAppLink ? (NSURL *)request.url() : nil).get()]; > } > >-void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, const ResourceRequest& request, bool, FormState* formState, PolicyDecisionMode, FramePolicyFunction&& function) >+void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, const ResourceRequest& request, bool, RedirectedByClient, FormState* formState, PolicyDecisionMode, FramePolicyFunction&& function) > { > WebView *webView = getWebView(m_webFrame.get()); > BOOL tryAppLink = shouldTryAppLink(webView, action, core(m_webFrame.get())); >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 1ad6b83000ce08bfe8d1fe6481ebc1a48f301efe..7d9de3b8a199a75228059aac1aaf2a98037e3ffc 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,30 @@ >+2018-06-11 Ali Juma <ajuma@chromium.org> >+ >+ Use SafeBrowsing in WKWebView >+ https://bugs.webkit.org/show_bug.cgi?id=181804 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Enable SafeBrowsing in MiniBrowser. >+ >+ Add API tests for SafeBrowsing. >+ >+ * MiniBrowser/MiniBrowser.entitlements: >+ * MiniBrowser/mac/AppDelegate.m: >+ (defaultConfiguration): >+ * MiniBrowser/mac/WK2BrowserWindowController.m: >+ (-[WK2BrowserWindowController webView:decidePolicyForSafeBrowsingResultForNavigationAction:decisionHandler:]): >+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: >+ * TestWebKitAPI/Tests/WebKitCocoa/SafeBrowsing.mm: Added. >+ (-[SBScheme webView:startURLSchemeTask:]): >+ (-[SBScheme webView:stopURLSchemeTask:]): >+ (-[SafeBrowsingTestController webView:decidePolicyForNavigationAction:decisionHandler:]): >+ (-[SafeBrowsingTestController webView:decidePolicyForSafeBrowsingResultForNavigationAction:decisionHandler:]): >+ (-[SafeBrowsingTestController webView:didFinishNavigation:]): >+ (TEST): >+ * TestWebKitAPI/Tests/WebKitCocoa/redirect-to-unsafe.html: Added. >+ * TestWebKitAPI/Tests/WebKitCocoa/unsafe-iframe.html: Added. >+ > 2018-06-11 Philippe Normand <pnormand@igalia.com> > > [webkitpy] PHP7.2 support on Debian platforms >diff --git a/Tools/MiniBrowser/MiniBrowser.entitlements b/Tools/MiniBrowser/MiniBrowser.entitlements >index ea26ab2421009df705a6b9f01bcd33b3f8975752..a72c4ce64dac6ef0d16770e8faee48c23a9ff5f0 100644 >--- a/Tools/MiniBrowser/MiniBrowser.entitlements >+++ b/Tools/MiniBrowser/MiniBrowser.entitlements >@@ -4,6 +4,8 @@ > <dict> > <key>com.apple.security.app-sandbox</key> > <true/> >+ <key>com.apple.security.temporary-exception.mach-lookup.global-name</key> >+ <string>com.apple.Safari.SafeBrowsing.Service</string> > <key>com.apple.security.network.client</key> > <true/> > <key>com.apple.security.temporary-exception.files.absolute-path.read-only</key> >diff --git a/Tools/MiniBrowser/mac/AppDelegate.m b/Tools/MiniBrowser/mac/AppDelegate.m >index 3a369a409c4bcda75a1136c1123a0863d5770ea7..b24c78dd79ce7194e6e3483b661b0bd8a564e079 100644 >--- a/Tools/MiniBrowser/mac/AppDelegate.m >+++ b/Tools/MiniBrowser/mac/AppDelegate.m >@@ -93,6 +93,7 @@ - (void)awakeFromNib > configuration = [[WKWebViewConfiguration alloc] init]; > configuration.preferences._fullScreenEnabled = YES; > configuration.preferences._developerExtrasEnabled = YES; >+ configuration.preferences.safeBrowsingEnabled = YES; > > _WKProcessPoolConfiguration *processConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease]; > processConfiguration.diskCacheSpeculativeValidationEnabled = ![SettingsController shared].networkCacheSpeculativeRevalidationDisabled; >diff --git a/Tools/MiniBrowser/mac/WK2BrowserWindowController.m b/Tools/MiniBrowser/mac/WK2BrowserWindowController.m >index 3ead630a78928a19ffecbedbf5155d516bb88c1a..7a5b955562299a1e6f05ad20238f3da80260a2d6 100644 >--- a/Tools/MiniBrowser/mac/WK2BrowserWindowController.m >+++ b/Tools/MiniBrowser/mac/WK2BrowserWindowController.m >@@ -641,6 +641,11 @@ - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigati > decisionHandler(WKNavigationActionPolicyCancel); > } > >+- (void)webView:(WKWebView *)webView decidePolicyForSafeBrowsingResultForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKSafeBrowsingResultPolicy))decisionHandler >+{ >+ decisionHandler(WKSafeBrowsingResultPolicyCancelAndShowWarning); >+} >+ > - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler > { > LOG(@"decidePolicyForNavigationResponse"); >diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >index 128a87a661ec6012493e7c263d5b4382a91b15a0..834461f78421d15cdd832792a4002557f8f73026 100644 >--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >@@ -298,6 +298,9 @@ > 7673499D1930C5BB00E44DF9 /* StopLoadingDuringDidFailProvisionalLoad_bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7673499A1930182E00E44DF9 /* StopLoadingDuringDidFailProvisionalLoad_bundle.cpp */; }; > 76E182DD1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */; }; > 76E182DF154767E600F1FADD /* auto-submitting-form.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 76E182DE15475A8300F1FADD /* auto-submitting-form.html */; }; >+ 7727593C20C1BC8400D88206 /* SafeBrowsing.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7727593A20C1BC7400D88206 /* SafeBrowsing.mm */; }; >+ 7731562820C8572100E8C6DE /* redirect-to-unsafe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 7731562520C83A9000E8C6DE /* redirect-to-unsafe.html */; }; >+ 7731562A20C8726700E8C6DE /* unsafe-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 7731562920C8721200E8C6DE /* unsafe-iframe.html */; }; > 79C5D431209D768300F1E7CA /* InjectedBundleNodeHandleIsTextField.mm in Sources */ = {isa = PBXBuildFile; fileRef = 79C5D430209D768300F1E7CA /* InjectedBundleNodeHandleIsTextField.mm */; }; > 7A010BCB1D877C0500EDE72A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A010BCA1D877C0500EDE72A /* CoreGraphics.framework */; }; > 7A010BCD1D877C0D00EDE72A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A010BCC1D877C0D00EDE72A /* QuartzCore.framework */; }; >@@ -1088,6 +1091,7 @@ > F41AB9A81EF4696B0083FA08 /* prevent-operation.html in Copy Resources */, > F41AB9A91EF4696B0083FA08 /* prevent-start.html in Copy Resources */, > F6FDDDD614241C6F004F1729 /* push-state.html in Copy Resources */, >+ 7731562820C8572100E8C6DE /* redirect-to-unsafe.html in Copy Resources */, > A12DDC001E8373E700CF6CAE /* rendered-image-excluding-overflow.html in Copy Resources */, > F46849C01EEF5EF300B937FE /* rich-and-plain-text.html in Copy Resources */, > 0F5651F91FCE513500310FBC /* scroll-to-anchor.html in Copy Resources */, >@@ -1119,6 +1123,7 @@ > 2E9896151D8F093800739892 /* text-and-password-inputs.html in Copy Resources */, > F41AB9AA1EF4696B0083FA08 /* textarea-to-input.html in Copy Resources */, > F4451C761EB8FD890020C5DA /* two-paragraph-contenteditable.html in Copy Resources */, >+ 7731562A20C8726700E8C6DE /* unsafe-iframe.html in Copy Resources */, > C540F784152E5A9A00A40C8C /* verboseMarkup.html in Copy Resources */, > CDC8E4941BC6F10800594FEC /* video-with-audio.html in Copy Resources */, > CDC8E4951BC6F10800594FEC /* video-with-audio.mp4 in Copy Resources */, >@@ -1528,6 +1533,9 @@ > 76E182D91547550100F1FADD /* WillSendSubmitEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillSendSubmitEvent.cpp; sourceTree = "<group>"; }; > 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillSendSubmitEvent_Bundle.cpp; sourceTree = "<group>"; }; > 76E182DE15475A8300F1FADD /* auto-submitting-form.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "auto-submitting-form.html"; sourceTree = "<group>"; }; >+ 7727593A20C1BC7400D88206 /* SafeBrowsing.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SafeBrowsing.mm; sourceTree = "<group>"; }; >+ 7731562520C83A9000E8C6DE /* redirect-to-unsafe.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "redirect-to-unsafe.html"; sourceTree = "<group>"; }; >+ 7731562920C8721200E8C6DE /* unsafe-iframe.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "unsafe-iframe.html"; sourceTree = "<group>"; }; > 79C5D430209D768300F1E7CA /* InjectedBundleNodeHandleIsTextField.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InjectedBundleNodeHandleIsTextField.mm; sourceTree = "<group>"; }; > 7A010BCA1D877C0500EDE72A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; > 7A010BCC1D877C0D00EDE72A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; >@@ -2260,6 +2268,7 @@ > CD9E292B1C90A71F000BB800 /* RequiresUserActionForPlayback.mm */, > 51C8E1A41F26AC5400BF731B /* ResourceLoadStatistics.mm */, > A180C0F91EE67DF000468F47 /* RunOpenPanel.mm */, >+ 7727593A20C1BC7400D88206 /* SafeBrowsing.mm */, > CE0947362063223B003C9BA0 /* SchemeRegistry.mm */, > 51EB12931FDF050500A5A1BD /* ServiceWorkerBasic.mm */, > 37BCA61B1B596BA9002012CA /* ShouldOpenExternalURLsInNewWindowActions.mm */, >@@ -2589,6 +2598,7 @@ > F415086C1DA040C10044BE9B /* play-audio-on-click.html */, > F41AB9941EF4692C0083FA08 /* prevent-operation.html */, > F41AB99A1EF4692C0083FA08 /* prevent-start.html */, >+ 7731562520C83A9000E8C6DE /* redirect-to-unsafe.html */, > A12DDBFF1E8373C100CF6CAE /* rendered-image-excluding-overflow.html */, > F46849BF1EEF5EDC00B937FE /* rich-and-plain-text.html */, > F4D65DA71F5E46C0009D8C27 /* selected-text-image-link-and-editable.html */, >@@ -2602,6 +2612,7 @@ > 2E9896141D8F092B00739892 /* text-and-password-inputs.html */, > F41AB9951EF4692C0083FA08 /* textarea-to-input.html */, > F4451C751EB8FD7C0020C5DA /* two-paragraph-contenteditable.html */, >+ 7731562920C8721200E8C6DE /* unsafe-iframe.html */, > 51714EB21CF8C761004723C4 /* WebProcessKillIDBCleanup-1.html */, > 51714EB31CF8C761004723C4 /* WebProcessKillIDBCleanup-2.html */, > 5120C83B1E674E350025B250 /* WebsiteDataStoreCustomPaths.html */, >@@ -3750,6 +3761,7 @@ > 46E816F81E79E29C00375ADC /* RestoreStateAfterTermination.mm in Sources */, > F418BE151F71B7DC001970E6 /* RoundedRectTests.cpp in Sources */, > A180C0FA1EE67DF000468F47 /* RunOpenPanel.mm in Sources */, >+ 7727593C20C1BC8400D88206 /* SafeBrowsing.mm in Sources */, > CDCFA7AA1E45183200C2433D /* SampleMap.cpp in Sources */, > CE0947372063223B003C9BA0 /* SchemeRegistry.mm in Sources */, > 7CCE7F121A411AE600447C4C /* ScrollPinningBehaviors.cpp in Sources */, >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/SafeBrowsing.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/SafeBrowsing.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..f0ababcd9e40c389bd3c11aef9bd59427f060dd0 >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/SafeBrowsing.mm >@@ -0,0 +1,529 @@ >+/* >+ * Copyright (C) 2018 Google LLC. 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. >+ */ >+ >+#include "config.h" >+ >+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) >+ >+#import "PlatformUtilities.h" >+#import "TestProtocol.h" >+#import <WebKit/WKNavigationActionPrivate.h> >+#import <WebKit/WKWebViewConfiguration.h> >+#import <WebKit/WKWebViewPrivate.h> >+#import <wtf/RetainPtr.h> >+ >+#if WK_API_ENABLED >+ >+static bool shouldCancelNavigation; >+static bool shouldCancelForSafeBrowsing; >+static bool shouldShowSafeBrowsingWarning; >+static bool decidedNavigationPolicy; >+static bool decidedSafeBrowsingPolicy; >+static bool finishedNavigation; >+static bool finishedRedirectNavigation; >+ >+static NSString *firstURL = @"data:text/html,First"; >+static NSString *secondURL = @"data:text/html,Second"; >+static NSString *unsafeURL = @"sb://host/phishing.html"; >+static NSString *warningURL = @"file:///SafeBrowsing"; >+ >+@interface SBScheme : NSObject <WKURLSchemeHandler> >+@end >+ >+@implementation SBScheme >+ >+- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask >+{ >+ NSString *data = @"Lorem ipsum dolor sit amet"; >+ [urlSchemeTask didReceiveResponse:[[[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:@"text/html" expectedContentLength:data.length textEncodingName:nil] autorelease]]; >+ [urlSchemeTask didReceiveData:[data dataUsingEncoding:NSUTF8StringEncoding]]; >+ [urlSchemeTask didFinish]; >+} >+ >+- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask >+{ >+} >+ >+@end >+ >+@interface SafeBrowsingTestController : NSObject <WKNavigationDelegate, WKUIDelegate> >+@end >+ >+@implementation SafeBrowsingTestController >+ >+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler >+{ >+ if (shouldCancelNavigation) >+ decisionHandler(WKNavigationActionPolicyCancel); >+ else >+ decisionHandler(WKNavigationActionPolicyAllow); >+ decidedNavigationPolicy = true; >+} >+ >+- (void)webView:(WKWebView*)webView decidePolicyForSafeBrowsingResultForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKSafeBrowsingResultPolicy))decisionHandler >+{ >+ if (shouldCancelForSafeBrowsing) >+ decisionHandler(WKSafeBrowsingResultPolicyCancel); >+ else if (shouldShowSafeBrowsingWarning) >+ decisionHandler(WKSafeBrowsingResultPolicyCancelAndShowWarning); >+ else >+ decisionHandler(WKSafeBrowsingResultPolicyAllow); >+ decidedSafeBrowsingPolicy = true; >+} >+ >+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation >+{ >+ if (finishedNavigation) >+ finishedRedirectNavigation = true; >+ else >+ finishedNavigation = true; >+} >+ >+ >+@end >+ >+TEST(WebKit, SafeBrowsingForSafePage) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_FALSE(decidedSafeBrowsingPolicy); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafePageAllow) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:unsafeURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_TRUE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], ""); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafePageShowWarning) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldShowSafeBrowsingWarning = true; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:unsafeURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ shouldShowSafeBrowsingWarning = false; >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_TRUE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], warningURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], unsafeURL); >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ [webView evaluateJavaScript:@"var evt = document.createEvent('MouseEvent'); evt.initMouseEvent('click'); document.getElementById('visitAnyway').dispatchEvent(evt);" completionHandler:nil]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_FALSE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], ""); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafePageShowWarningBackForward) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldShowSafeBrowsingWarning = true; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:unsafeURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ shouldShowSafeBrowsingWarning = false; >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_TRUE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], warningURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], unsafeURL); >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:secondURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldShowSafeBrowsingWarning = true; >+ [webView goBack]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ shouldShowSafeBrowsingWarning = false; >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_TRUE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] forwardItem] URL] absoluteString], secondURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], warningURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], unsafeURL); >+ >+ finishedNavigation = false; >+ [webView goBack]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] forwardItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], firstURL); >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldShowSafeBrowsingWarning = true; >+ [webView goForward]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ shouldShowSafeBrowsingWarning = false; >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_TRUE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] forwardItem] URL] absoluteString], secondURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], warningURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], unsafeURL); >+ >+ finishedNavigation = false; >+ [webView goForward]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], secondURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], secondURL); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafePageCancelForSafeBrowsing) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldCancelForSafeBrowsing = true; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:unsafeURL]]]; >+ TestWebKitAPI::Util::run(&decidedSafeBrowsingPolicy); >+ shouldCancelForSafeBrowsing = false; >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_FALSE(finishedNavigation); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], ""); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafePageCancelNavigation) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldCancelNavigation = true; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:unsafeURL]]]; >+ TestWebKitAPI::Util::run(&decidedNavigationPolicy); >+ shouldCancelNavigation = false; >+ >+ EXPECT_FALSE(decidedSafeBrowsingPolicy); >+ EXPECT_FALSE(finishedNavigation); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], ""); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafePageRedirectShowWarning) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ finishedRedirectNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldShowSafeBrowsingWarning = true; >+ [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"redirect-to-unsafe" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; >+ TestWebKitAPI::Util::run(&finishedRedirectNavigation); >+ shouldShowSafeBrowsingWarning = false; >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_TRUE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], warningURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], unsafeURL); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafePageRedirectAllow) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ finishedRedirectNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"redirect-to-unsafe" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]]; >+ TestWebKitAPI::Util::run(&finishedRedirectNavigation); >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_TRUE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], unsafeURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], ""); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafePageRedirectCancel) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ finishedRedirectNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldCancelForSafeBrowsing = true; >+ NSURLRequest* request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"redirect-to-unsafe" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]; >+ [webView loadRequest:request]; >+ TestWebKitAPI::Util::run(&decidedSafeBrowsingPolicy); >+ shouldCancelForSafeBrowsing = false; >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], [[request URL] absoluteString]); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], [[request URL] absoluteString]); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], [[request URL] absoluteString]); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], ""); >+} >+ >+TEST(WebKit, SafeBrowsingForUnsafeSubframeShowWarning) >+{ >+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ RetainPtr<SBScheme> handler = adoptNS([[SBScheme alloc] init]); >+ [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SB"]; >+ [configuration preferences].safeBrowsingEnabled = YES; >+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); >+ [webView _setUseTestSafeBrowsingContext:YES]; >+ >+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]); >+ [[window contentView] addSubview:webView.get()]; >+ >+ auto controller = adoptNS([[SafeBrowsingTestController alloc] init]); >+ [webView setNavigationDelegate:controller.get()]; >+ [webView setUIDelegate:controller.get()]; >+ >+ finishedNavigation = false; >+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]]; >+ TestWebKitAPI::Util::run(&finishedNavigation); >+ >+ finishedNavigation = false; >+ finishedRedirectNavigation = false; >+ decidedNavigationPolicy = false; >+ decidedSafeBrowsingPolicy = false; >+ shouldShowSafeBrowsingWarning = true; >+ NSURLRequest* request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"unsafe-iframe" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]; >+ [webView loadRequest:request]; >+ TestWebKitAPI::Util::run(&finishedRedirectNavigation); >+ shouldShowSafeBrowsingWarning = false; >+ >+ EXPECT_TRUE(decidedNavigationPolicy); >+ EXPECT_TRUE(decidedSafeBrowsingPolicy); >+ EXPECT_WK_STREQ([[[[webView backForwardList] currentItem] URL] absoluteString], [[request URL] absoluteString]); >+ EXPECT_WK_STREQ([[[[webView backForwardList] backItem] URL] absoluteString], firstURL); >+ EXPECT_WK_STREQ([[webView URL] absoluteString], [[request URL] absoluteString]); >+ EXPECT_WK_STREQ([[webView _committedURL] absoluteString], warningURL); >+ EXPECT_WK_STREQ([[webView _unreachableURL] absoluteString], [[request URL] absoluteString]); >+} >+ >+#endif >+ >+#endif >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/redirect-to-unsafe.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/redirect-to-unsafe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7d9dbf6caab71d949c8001930c595a518b0b9359 >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/redirect-to-unsafe.html >@@ -0,0 +1,4 @@ >+<!DOCTYPE html> >+<head> >+ <script>window.location = 'sb://host/phishing.html';</script> >+</head> >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/unsafe-iframe.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/unsafe-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9ecf280b2ec40b4a7cf576c6802902333e1d2efd >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/unsafe-iframe.html >@@ -0,0 +1,2 @@ >+<!DOCTYPE html> >+<iframe src='sb://host/phishing.html'></iframe>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185273
:
339558
|
339580
|
339730
|
340500
|
340514
|
340519
|
341674
|
341677
|
342442
|
342444
|
342446
|
342459
|
342555
|
342591
|
342674
|
342682
|
342977
|
343043
|
343090
|
344296
|
344297