Diff
Modified: branches/safari-610.1.11-branch/Source/WebKit/ChangeLog (260917 => 260918)
--- branches/safari-610.1.11-branch/Source/WebKit/ChangeLog 2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Source/WebKit/ChangeLog 2020-04-29 22:13:28 UTC (rev 260918)
@@ -1,3 +1,93 @@
+2020-04-29 Alan Coon <[email protected]>
+
+ Cherry-pick r260408. rdar://problem/62617775
+
+ App-bound domain behavior should abide by the limitsNavigationsToAppBoundDomains argument in WKWebView configuration
+ https://bugs.webkit.org/show_bug.cgi?id=210769
+ <rdar://problem/62065241>
+
+ Reviewed by Brent Fulgham.
+
+ Source/WebKit:
+
+ Changes app-bound domain behavior to be triggered by the value of
+ limitsNavigationsToAppBoundDomains, a WebView configuration flag.
+ If the WebView has this parameter set and is currently navigating to
+ an app bound domain, then app-bound privileges will be granted.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
+ Update this function to return a boolean to indicate whether the
+ navigation should fail. A failure should occur if a WebView has set
+ the limitsNavigationsToAppBoundDomains flag and attempts to navigate
+ away from an app-bound domain.
+
+ If the limitsNavigationsToAppBoundDomains value has not been set to
+ true, maintain non-app bound behavior regardless of whether the domain
+ is app-bound or not.
+
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ Check the result of setIsNavigatingToAppBoundDomainAndCheckIfPermitted and fail the
+ navigation if needed, with both RELEASE logging and an appropriate
+ error message.
+
+ (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomain): Deleted.
+ * UIProcess/WebPageProxy.h:
+ Renamed for clarity.
+
+ Tools:
+
+ Removes any tests for swapping between app-bound and non app-bound
+ domains as this behavior is no longer supported.
+
+ Sets the limitsNavigationsToAppBoundDomains flag for tests which should
+ have app-bound behavior to maintain test functionality.
+
+ Adds 5 new tests for new behavior.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+ (TEST):
+ (-[AppBoundDomainDelegate webView:didFinishNavigation:]):
+ (-[AppBoundDomainDelegate webView:didFailProvisionalNavigation:withError:]):
+ (-[AppBoundDomainDelegate waitForDidFinishNavigation]):
+ (-[AppBoundDomainDelegate waitForDidFailProvisionalNavigationError]):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260408 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2020-04-20 Kate Cheney <[email protected]>
+
+ App-bound domain behavior should abide by the limitsNavigationsToAppBoundDomains argument in WKWebView configuration
+ https://bugs.webkit.org/show_bug.cgi?id=210769
+ <rdar://problem/62065241>
+
+ Reviewed by Brent Fulgham.
+
+ Changes app-bound domain behavior to be triggered by the value of
+ limitsNavigationsToAppBoundDomains, a WebView configuration flag.
+ If the WebView has this parameter set and is currently navigating to
+ an app bound domain, then app-bound privileges will be granted.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
+ Update this function to return a boolean to indicate whether the
+ navigation should fail. A failure should occur if a WebView has set
+ the limitsNavigationsToAppBoundDomains flag and attempts to navigate
+ away from an app-bound domain.
+
+ If the limitsNavigationsToAppBoundDomains value has not been set to
+ true, maintain non-app bound behavior regardless of whether the domain
+ is app-bound or not.
+
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ Check the result of setIsNavigatingToAppBoundDomainAndCheckIfPermitted and fail the
+ navigation if needed, with both RELEASE logging and an appropriate
+ error message.
+
+ (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomain): Deleted.
+ * UIProcess/WebPageProxy.h:
+ Renamed for clarity.
+
2020-04-27 Alan Coon <[email protected]>
Cherry-pick r260763. rdar://problem/62467013
Modified: branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.cpp (260917 => 260918)
--- branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-04-29 22:13:28 UTC (rev 260918)
@@ -3127,26 +3127,29 @@
PolicyCheckIdentifier m_identifier;
};
-void WebPageProxy::setIsNavigatingToAppBoundDomain(bool isMainFrame, const URL& requestURL, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain)
+bool WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted(bool isMainFrame, const URL& requestURL, Optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain)
{
#if PLATFORM(IOS_FAMILY)
if (isMainFrame) {
if (WEB_PAGE_PROXY_ADDITIONS_SETISNAVIGATINGTOAPPBOUNDDOMAIN)
- return;
+ return true;
if (!isNavigatingToAppBoundDomain) {
m_isNavigatingToAppBoundDomain = WTF::nullopt;
- return;
+ return true;
}
if (m_ignoresAppBoundDomains)
- return;
- if (*isNavigatingToAppBoundDomain == NavigatingToAppBoundDomain::No) {
+ return true;
+
+ if (m_limitsNavigationsToAppBoundDomains) {
+ if (*isNavigatingToAppBoundDomain == NavigatingToAppBoundDomain::No)
+ return false;
+ m_configuration->setWebViewCategory(WebViewCategory::AppBoundDomain);
+ m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::Yes;
+ } else {
m_configuration->setWebViewCategory(WebViewCategory::InAppBrowser);
m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::No;
m_hasNavigatedAwayFromAppBoundDomain = NavigatedAwayFromAppBoundDomain::Yes;
- return;
}
- m_configuration->setWebViewCategory(WebViewCategory::AppBoundDomain);
- m_isNavigatingToAppBoundDomain = NavigatingToAppBoundDomain::Yes;
}
#else
UNUSED_PARAM(isMainFrame);
@@ -3153,6 +3156,7 @@
UNUSED_PARAM(requestURL);
UNUSED_PARAM(isNavigatingToAppBoundDomain);
#endif
+ return true;
}
void WebPageProxy::isNavigatingToAppBoundDomainTesting(CompletionHandler<void(bool)>&& completionHandler)
@@ -5155,11 +5159,8 @@
shouldExpectAppBoundDomainResult = ShouldExpectAppBoundDomainResult::Yes;
#endif
- auto listener = makeRef(frame.setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frame = makeRef(frame), sender = WTFMove(sender), navigation] (PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, Optional<NavigatingToAppBoundDomain> isAppBoundDomain) mutable {
+ auto listener = makeRef(frame.setUpPolicyListenerProxy([this, protectedThis = makeRef(*this), frame = makeRef(frame), sender = WTFMove(sender), navigation, frameInfo, userDataObject = process->transformHandlesToObjects(userData.object()).get()] (PolicyAction policyAction, API::WebsitePolicies* policies, ProcessSwapRequestedByClient processSwapRequestedByClient, RefPtr<SafeBrowsingWarning>&& safeBrowsingWarning, Optional<NavigatingToAppBoundDomain> isAppBoundDomain) mutable {
- if (policyAction != PolicyAction::Ignore)
- setIsNavigatingToAppBoundDomain(frame->isMainFrame(), navigation->currentRequest().url(), isAppBoundDomain);
-
auto completionHandler = [this, protectedThis = protectedThis.copyRef(), frame = frame.copyRef(), sender = WTFMove(sender), navigation, processSwapRequestedByClient, policies = makeRefPtr(policies)] (PolicyAction policyAction) mutable {
if (frame->isMainFrame()) {
if (!policies) {
@@ -5171,6 +5172,16 @@
}
receivedNavigationPolicyDecision(policyAction, navigation.get(), processSwapRequestedByClient, frame, WTFMove(policies), WTFMove(sender));
};
+
+ if (policyAction != PolicyAction::Ignore) {
+ if (!setIsNavigatingToAppBoundDomainAndCheckIfPermitted(frame->isMainFrame(), navigation->currentRequest().url(), isAppBoundDomain)) {
+ auto error = ResourceError { String { }, 0, navigation->currentRequest().url(), "Attempted navigation away from app-bound domain"_s };
+ m_navigationClient->didFailProvisionalNavigationWithError(*this, FrameInfoData { frameInfo }, navigation.get(), error, userDataObject);
+ RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "Ignoring request to load this main resource because it is attempting to navigate away from an app-bound domain");
+ completionHandler(PolicyAction::Ignore);
+ return;
+ }
+ }
if (!m_pageClient)
return completionHandler(policyAction);
Modified: branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.h (260917 => 260918)
--- branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.h 2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Source/WebKit/UIProcess/WebPageProxy.h 2020-04-29 22:13:28 UTC (rev 260918)
@@ -2303,7 +2303,7 @@
void tryCloseTimedOut();
void makeStorageSpaceRequest(WebCore::FrameIdentifier, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&&);
- void setIsNavigatingToAppBoundDomain(bool isMainFrame, const URL&, Optional<NavigatingToAppBoundDomain>);
+ bool setIsNavigatingToAppBoundDomainAndCheckIfPermitted(bool isMainFrame, const URL&, Optional<NavigatingToAppBoundDomain>);
NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain() const { return m_hasNavigatedAwayFromAppBoundDomain; }
const Identifier m_identifier;
Modified: branches/safari-610.1.11-branch/Tools/ChangeLog (260917 => 260918)
--- branches/safari-610.1.11-branch/Tools/ChangeLog 2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Tools/ChangeLog 2020-04-29 22:13:28 UTC (rev 260918)
@@ -1,3 +1,83 @@
+2020-04-29 Alan Coon <[email protected]>
+
+ Cherry-pick r260408. rdar://problem/62617775
+
+ App-bound domain behavior should abide by the limitsNavigationsToAppBoundDomains argument in WKWebView configuration
+ https://bugs.webkit.org/show_bug.cgi?id=210769
+ <rdar://problem/62065241>
+
+ Reviewed by Brent Fulgham.
+
+ Source/WebKit:
+
+ Changes app-bound domain behavior to be triggered by the value of
+ limitsNavigationsToAppBoundDomains, a WebView configuration flag.
+ If the WebView has this parameter set and is currently navigating to
+ an app bound domain, then app-bound privileges will be granted.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomainAndCheckIfPermitted):
+ Update this function to return a boolean to indicate whether the
+ navigation should fail. A failure should occur if a WebView has set
+ the limitsNavigationsToAppBoundDomains flag and attempts to navigate
+ away from an app-bound domain.
+
+ If the limitsNavigationsToAppBoundDomains value has not been set to
+ true, maintain non-app bound behavior regardless of whether the domain
+ is app-bound or not.
+
+ (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+ Check the result of setIsNavigatingToAppBoundDomainAndCheckIfPermitted and fail the
+ navigation if needed, with both RELEASE logging and an appropriate
+ error message.
+
+ (WebKit::WebPageProxy::setIsNavigatingToAppBoundDomain): Deleted.
+ * UIProcess/WebPageProxy.h:
+ Renamed for clarity.
+
+ Tools:
+
+ Removes any tests for swapping between app-bound and non app-bound
+ domains as this behavior is no longer supported.
+
+ Sets the limitsNavigationsToAppBoundDomains flag for tests which should
+ have app-bound behavior to maintain test functionality.
+
+ Adds 5 new tests for new behavior.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+ (TEST):
+ (-[AppBoundDomainDelegate webView:didFinishNavigation:]):
+ (-[AppBoundDomainDelegate webView:didFailProvisionalNavigation:withError:]):
+ (-[AppBoundDomainDelegate waitForDidFinishNavigation]):
+ (-[AppBoundDomainDelegate waitForDidFailProvisionalNavigationError]):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260408 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2020-04-20 Kate Cheney <[email protected]>
+
+ App-bound domain behavior should abide by the limitsNavigationsToAppBoundDomains argument in WKWebView configuration
+ https://bugs.webkit.org/show_bug.cgi?id=210769
+ <rdar://problem/62065241>
+
+ Reviewed by Brent Fulgham.
+
+ Removes any tests for swapping between app-bound and non app-bound
+ domains as this behavior is no longer supported.
+
+ Sets the limitsNavigationsToAppBoundDomains flag for tests which should
+ have app-bound behavior to maintain test functionality.
+
+ Adds 5 new tests for new behavior.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+ (TEST):
+ (-[AppBoundDomainDelegate webView:didFinishNavigation:]):
+ (-[AppBoundDomainDelegate webView:didFailProvisionalNavigation:withError:]):
+ (-[AppBoundDomainDelegate waitForDidFinishNavigation]):
+ (-[AppBoundDomainDelegate waitForDidFailProvisionalNavigationError]):
+
2020-04-24 Alan Coon <[email protected]>
Cherry-pick r260486. rdar://problem/62349885
Modified: branches/safari-610.1.11-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (260917 => 260918)
--- branches/safari-610.1.11-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2020-04-29 21:57:41 UTC (rev 260917)
+++ branches/safari-610.1.11-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm 2020-04-29 22:13:28 UTC (rev 260918)
@@ -220,49 +220,6 @@
TestWebKitAPI::Util::run(&isDone);
}
-TEST(InAppBrowserPrivacy, SwapBackToAppBoundRejectsUserScript)
-{
- initializeInAppBrowserPrivacyTestSettings();
- auto userScript = adoptNS([[WKUserScript alloc] initWithSource:userScriptSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]);
-
- WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
- [[configuration preferences] _setNeedsInAppBrowserPrivacyQuirks:NO];
- [[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
-
- auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
- [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
-
- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
- NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-script"]];
- [webView loadRequest:request];
- [webView _test_waitForDidFinishNavigation];
-
- [configuration.userContentController _addUserScriptImmediately:userScript.get()];
- [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
- EXPECT_FALSE(result);
- EXPECT_TRUE(!!error);
- isDone = true;
- }];
-
- isDone = false;
- TestWebKitAPI::Util::run(&isDone);
-
- request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
- [webView loadRequest:request];
- [webView _test_waitForDidFinishNavigation];
-
- isDone = false;
- [configuration.userContentController _addUserScriptImmediately:userScript.get()];
- [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
- EXPECT_FALSE(result);
- EXPECT_TRUE(!!error);
- cleanUpInAppBrowserPrivacyTestSettings();
- isDone = true;
- }];
-
- TestWebKitAPI::Util::run(&isDone);
-}
-
TEST(InAppBrowserPrivacy, AppBoundDomains)
{
initializeInAppBrowserPrivacyTestSettings();
@@ -288,6 +245,7 @@
initializeInAppBrowserPrivacyTestSettings();
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
[[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+ [configuration setLimitsNavigationsToAppBoundDomains:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
@@ -308,6 +266,7 @@
initializeInAppBrowserPrivacyTestSettings();
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
[[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+ [configuration setLimitsNavigationsToAppBoundDomains:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"data:text/html,start"]]];
@@ -327,6 +286,7 @@
initializeInAppBrowserPrivacyTestSettings();
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
[[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+ [configuration setLimitsNavigationsToAppBoundDomains:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
@@ -345,6 +305,7 @@
static NSString *backgroundColorScript = @"window.getComputedStyle(document.body, null).getPropertyValue('background-color')";
static NSString *frameBackgroundColorScript = @"window.getComputedStyle(document.getElementsByTagName('iframe')[0].contentDocument.body, null).getPropertyValue('background-color')";
static const char* redInRGB = "rgb(255, 0, 0)";
+static const char* blackInRGB = "rgba(0, 0, 0, 0)";
static void expectScriptEvaluatesToColor(WKWebView *webView, NSString *script, const char* color)
{
@@ -458,7 +419,7 @@
cleanUpInAppBrowserPrivacyTestSettings();
}
-TEST(InAppBrowserPrivacy, AppBoundToNonAppBoundDomainCannotAccessMessageHandlers)
+TEST(InAppBrowserPrivacy, AppBoundDomainCanAccessMessageHandlers)
{
initializeInAppBrowserPrivacyTestSettings();
isDone = false;
@@ -468,6 +429,7 @@
auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
[configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
[[configuration preferences] _setInAppBrowserPrivacyEnabled:YES];
+ [configuration setLimitsNavigationsToAppBoundDomains:YES];
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
@@ -486,14 +448,6 @@
FAIL();
}];
- // Navigate away from an app-bound domain.
- NSURLRequest *request2 = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-message-handler"]];
- [webView loadRequest:request2];
- [webView _test_waitForDidFinishNavigation];
-
- // Set the background color to red if message handlers returned null so we can
- // check without needing a message handler.
- expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
cleanUpInAppBrowserPrivacyTestSettings();
}
@@ -875,6 +829,205 @@
isDone = false;
}
+@interface AppBoundDomainDelegate : NSObject <WKNavigationDelegate>
+- (void)waitForDidFinishNavigation;
+- (NSError *)waitForDidFailProvisionalNavigationError;
+@end
+
+@implementation AppBoundDomainDelegate {
+ bool _navigationFinished;
+ RetainPtr<NSError> _provisionalNavigationFailedError;
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
+{
+ _navigationFinished = true;
+}
+
+- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
+{
+ _provisionalNavigationFailedError = error;
+}
+
+- (void)waitForDidFinishNavigation
+{
+ TestWebKitAPI::Util::run(&_navigationFinished);
+}
+
+- (NSError *)waitForDidFailProvisionalNavigationError
+{
+ while (!_provisionalNavigationFailedError)
+ TestWebKitAPI::Util::spinRunLoop();
+ return _provisionalNavigationFailedError.autorelease();
+}
+
+@end
+
+TEST(InAppBrowserPrivacy, AppBoundFlagForNonAppBoundDomainFails)
+{
+ initializeInAppBrowserPrivacyTestSettings();
+ isDone = false;
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+ [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+ [configuration setLimitsNavigationsToAppBoundDomains:YES];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ // Load a non-app bound domain.
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+ [webView loadRequest:request];
+ NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+ EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+
+ // Make sure the load didn't complete by checking the background color.
+ // Red would indicate it finished loading.
+ expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, blackInRGB);
+ cleanUpInAppBrowserPrivacyTestSettings();
+}
+
+TEST(InAppBrowserPrivacy, NavigateAwayFromAppBoundDomainWithAppBoundFlagFails)
+{
+ initializeInAppBrowserPrivacyTestSettings();
+ isDone = false;
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+ [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+ [configuration setLimitsNavigationsToAppBoundDomains:YES];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ // Navigate to an app-bound domain and expect a successful load.
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:request];
+ [delegate waitForDidFinishNavigation];
+
+ // Now try to load a non-app bound domain and make sure it fails.
+ request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+ [webView loadRequest:request];
+ NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+ EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+
+ // Make sure the load didn't complete by checking the background color.
+ // Red would indicate it finished loading.
+ expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, blackInRGB);
+ cleanUpInAppBrowserPrivacyTestSettings();
+}
+
+TEST(InAppBrowserPrivacy, AppBoundDomainWithoutFlagTreatedAsNonAppBound)
+{
+ initializeInAppBrowserPrivacyTestSettings();
+ isDone = false;
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+ [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ // Navigate to an app-bound domain and expect a successful load.
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:request];
+ [delegate waitForDidFinishNavigation];
+
+ // But the navigation should not have been considered app-bound because the WebView configuration
+ // specification was not set.
+ isDone = false;
+ [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
+ EXPECT_FALSE(isAppBound);
+ cleanUpInAppBrowserPrivacyTestSettings();
+ isDone = true;
+ }];
+ TestWebKitAPI::Util::run(&isDone);
+}
+
+TEST(InAppBrowserPrivacy, WebViewWithoutAppBoundFlagCanFreelyNavigate)
+{
+ initializeInAppBrowserPrivacyTestSettings();
+ isDone = false;
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+ [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ // Navigate to an app-bound domain and expect a successful load.
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:request];
+ [delegate waitForDidFinishNavigation];
+
+ isDone = false;
+ [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
+ EXPECT_FALSE(isAppBound);
+ isDone = true;
+ }];
+ TestWebKitAPI::Util::run(&isDone);
+
+ // Navigate to an non app-bound domain and expect a successful load.
+ request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+ [webView loadRequest:request];
+ [delegate waitForDidFinishNavigation];
+
+ isDone = false;
+ [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
+ EXPECT_FALSE(isAppBound);
+ isDone = true;
+ }];
+ TestWebKitAPI::Util::run(&isDone);
+
+ // Navigation should be successful, but this WebView should not get app-bound domain
+ // privileges like user style sheets.
+ expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, blackInRGB);
+ cleanUpInAppBrowserPrivacyTestSettings();
+}
+
+TEST(InAppBrowserPrivacy, WebViewCannotUpdateAppBoundFlagOnceSet)
+{
+ initializeInAppBrowserPrivacyTestSettings();
+ isDone = false;
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto schemeHandler = adoptNS([[InAppBrowserSchemeHandler alloc] init]);
+ [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"in-app-browser"];
+ [configuration setLimitsNavigationsToAppBoundDomains:YES];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ auto delegate = adoptNS([AppBoundDomainDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ // Navigate to an app-bound domain and expect a successful load.
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"in-app-browser-privacy-local-file" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:request];
+ [delegate waitForDidFinishNavigation];
+
+ isDone = false;
+ [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) {
+ EXPECT_TRUE(isAppBound);
+ isDone = true;
+ }];
+ TestWebKitAPI::Util::run(&isDone);
+
+ [[webView configuration] setLimitsNavigationsToAppBoundDomains:NO];
+ // Now try to load a non-app bound domain and make sure it fails.
+ request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"in-app-browser:///in-app-browser-privacy-test-user-style-sheets"]];
+ [webView loadRequest:request];
+ NSError *error = [delegate waitForDidFailProvisionalNavigationError];
+ EXPECT_WK_STREQ(error.localizedDescription, @"Attempted navigation away from app-bound domain");
+
+ cleanUpInAppBrowserPrivacyTestSettings();
+}
+
#endif // USE(APPLE_INTERNAL_SDK)
#endif // PLATFORM(IOS_FAMILY)