Changeset 263874 in webkit
- Timestamp:
- Jul 2, 2020, 4:15:47 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h (modified) (1 diff)
-
Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm (modified) (9 diffs)
-
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Info.plist (modified) (2 diffs)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r263869 r263874 1 2020-07-02 Kate Cheney <katherine_cheney@apple.com> 2 3 Custom URL schemes should be treated as app-bound 4 https://bugs.webkit.org/show_bug.cgi?id=213889 5 <rdar://problem/64804671> 6 7 Reviewed by Brent Fulgham. 8 9 For applications which opt-in to App-Bound Domains, allow 10 specification of app-bound custom URL schemes. All content loaded 11 using an app-bound scheme will have access to otherwise restricted 12 APIs. A custom scheme is specified by a colon at the end of a string 13 in the WKAppBoundDomains list. Custom schemes are included in the 14 count of 10 app-bound domains. 15 16 * UIProcess/API/Cocoa/WKWebsiteDataStore.mm: 17 (-[WKWebsiteDataStore _appBoundSchemes:]): 18 * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h: 19 SPI for testing. 20 21 * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm: 22 (WebKit::appBoundSchemes): 23 (WebKit::WebsiteDataStore::initializeAppBoundDomains): 24 Change variable name from appBoundDomains to appBoundData now that 25 more than domains can be specified in the Info.plist. 26 27 (WebKit::WebsiteDataStore::ensureAppBoundDomains const): 28 Return both domains and schemes to avoid code duplication, at the expense 29 of occasionally returning an unused parameter if only domains or only 30 schemes are needed. 31 32 (WebKit::WebsiteDataStore::beginAppBoundDomainCheck): 33 (WebKit::WebsiteDataStore::getAppBoundDomains const): 34 (WebKit::WebsiteDataStore::getAppBoundSchemes const): 35 * UIProcess/WebsiteData/WebsiteDataStore.h: 36 1 37 2020-07-02 Austin Blackwood <ablackwoood@apple.com> 2 38 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
r263570 r263874 643 643 } 644 644 645 - (void)_appBoundSchemes:(void (^)(NSArray<NSString *> *))completionHandler 646 { 647 _websiteDataStore->getAppBoundSchemes([completionHandler = makeBlockPtr(completionHandler)](auto& schemes) mutable { 648 Vector<RefPtr<API::Object>> apiSchemes; 649 apiSchemes.reserveInitialCapacity(schemes.size()); 650 for (auto& scheme : schemes) 651 apiSchemes.uncheckedAppend(API::String::create(scheme)); 652 completionHandler(wrapper(API::Array::create(WTFMove(apiSchemes)))); 653 }); 654 } 655 645 656 @end -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h
r261038 r263874 80 80 - (void)_processStatisticsAndDataRecords:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(10.15), ios(13.0)); 81 81 - (void)_appBoundDomains:(void (^)(NSArray<NSString *> *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 82 - (void)_appBoundSchemes:(void (^)(NSArray<NSString *> *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 82 83 83 84 - (void)_renameOrigin:(NSURL *)oldName to:(NSURL *)newName forDataOfTypes:(NSSet<NSString *> *)dataTypes completionHandler:(void (^)(void))completionHandler; -
trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm
r263441 r263874 406 406 } 407 407 408 static HashSet<String>& appBoundSchemes() 409 { 410 ASSERT(RunLoop::isMain()); 411 static NeverDestroyed<HashSet<String>> appBoundSchemes; 412 return appBoundSchemes; 413 } 414 408 415 void WebsiteDataStore::initializeAppBoundDomains(ForceReinitialization forceReinitialization) 409 416 { … … 419 426 return; 420 427 421 NSArray<NSString *> * domains= [[NSBundle mainBundle] objectForInfoDictionaryKey:@"WKAppBoundDomains"];422 keyExists = domains? true : false;428 NSArray<NSString *> *appBoundData = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"WKAppBoundDomains"]; 429 keyExists = appBoundData ? true : false; 423 430 424 RunLoop::main().dispatch([forceReinitialization, domains = retainPtr(domains)] {431 RunLoop::main().dispatch([forceReinitialization, appBoundData = retainPtr(appBoundData)] { 425 432 if (hasInitializedAppBoundDomains && forceReinitialization != ForceReinitialization::Yes) 426 433 return; … … 429 436 appBoundDomains().clear(); 430 437 431 for (NSString *domain in domains.get()) { 432 URL url { URL(), domain }; 438 for (NSString *data in appBoundData.get()) { 439 if (appBoundDomains().size() + appBoundSchemes().size() >= maxAppBoundDomainCount) 440 break; 441 if ([data hasSuffix:@":"]) { 442 auto appBoundScheme = String([data substringToIndex:[data length] - 1]); 443 if (!appBoundScheme.isEmpty()) { 444 appBoundSchemes().add(appBoundScheme); 445 continue; 446 } 447 } 448 449 URL url { URL(), data }; 433 450 if (url.protocol().isEmpty()) 434 451 url.setProtocol("https"); … … 439 456 continue; 440 457 appBoundDomains().add(appBoundDomain); 441 if (appBoundDomains().size() >= maxAppBoundDomainCount)442 break;443 458 } 444 459 hasInitializedAppBoundDomains = true; … … 449 464 } 450 465 451 void WebsiteDataStore::ensureAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>& )>&& completionHandler) const466 void WebsiteDataStore::ensureAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&, const HashSet<String>&)>&& completionHandler) const 452 467 { 453 468 if (hasInitializedAppBoundDomains) { … … 455 470 WEBSITE_DATA_STORE_ADDITIONS; 456 471 } 457 completionHandler(appBoundDomains() );472 completionHandler(appBoundDomains(), appBoundSchemes()); 458 473 return; 459 474 } … … 467 482 WEBSITE_DATA_STORE_ADDITIONS; 468 483 } 469 completionHandler(appBoundDomains() );484 completionHandler(appBoundDomains(), appBoundSchemes()); 470 485 }); 471 486 }); 472 487 } 473 488 489 static NavigatingToAppBoundDomain schemeOrDomainIsAppBound(const URL& requestURL, const HashSet<WebCore::RegistrableDomain>& domains, const HashSet<String>& schemes) 490 { 491 auto protocol = requestURL.protocol().toString(); 492 auto schemeIsAppBound = !protocol.isNull() && schemes.contains(protocol); 493 auto domainIsAppBound = domains.contains(WebCore::RegistrableDomain(requestURL)); 494 return schemeIsAppBound || domainIsAppBound ? NavigatingToAppBoundDomain::Yes : NavigatingToAppBoundDomain::No; 495 } 496 474 497 void WebsiteDataStore::beginAppBoundDomainCheck(const URL& requestURL, WebFramePolicyListenerProxy& listener) 475 498 { 476 499 ASSERT(RunLoop::isMain()); 477 500 478 ensureAppBoundDomains([&requestURL, listener = makeRef(listener)] (auto& domains ) mutable {501 ensureAppBoundDomains([&requestURL, listener = makeRef(listener)] (auto& domains, auto& schemes) mutable { 479 502 // Must check for both an empty app bound domains list and an empty key before returning nullopt 480 503 // because test cases may have app bound domains but no key. … … 484 507 return; 485 508 } 486 listener->didReceiveAppBoundDomainResult( domains.contains(WebCore::RegistrableDomain(requestURL)) ? NavigatingToAppBoundDomain::Yes : NavigatingToAppBoundDomain::No);509 listener->didReceiveAppBoundDomainResult(schemeOrDomainIsAppBound(requestURL, domains, schemes)); 487 510 }); 488 511 } … … 492 515 ASSERT(RunLoop::isMain()); 493 516 494 ensureAppBoundDomains([completionHandler = WTFMove(completionHandler)] (auto& domains ) mutable {517 ensureAppBoundDomains([completionHandler = WTFMove(completionHandler)] (auto& domains, auto& schemes) mutable { 495 518 completionHandler(domains); 519 }); 520 } 521 522 void WebsiteDataStore::getAppBoundSchemes(CompletionHandler<void(const HashSet<String>&)>&& completionHandler) const 523 { 524 ASSERT(RunLoop::isMain()); 525 526 ensureAppBoundDomains([completionHandler = WTFMove(completionHandler)] (auto& domains, auto& schemes) mutable { 527 completionHandler(schemes); 496 528 }); 497 529 } -
trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
r263736 r263874 302 302 void beginAppBoundDomainCheck(const URL&, WebFramePolicyListenerProxy&); 303 303 void getAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const; 304 void ensureAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&)>&&) const; 304 void getAppBoundSchemes(CompletionHandler<void(const HashSet<String>&)>&&) const; 305 void ensureAppBoundDomains(CompletionHandler<void(const HashSet<WebCore::RegistrableDomain>&, const HashSet<String>&)>&&) const; 305 306 void reinitializeAppBoundDomains(); 306 307 static void setAppBoundDomainsForTesting(HashSet<WebCore::RegistrableDomain>&&, CompletionHandler<void()>&&); -
trunk/Tools/ChangeLog
r263848 r263874 1 2020-07-02 Kate Cheney <katherine_cheney@apple.com> 2 3 Custom URL schemes should be treated as app-bound 4 https://bugs.webkit.org/show_bug.cgi?id=213889 5 <rdar://problem/64804671> 6 7 Reviewed by Brent Fulgham. 8 9 Added custom schemes to TestWebKitAPI's Info.plist for testing 10 duplicate values and the max of 10 domains/schemes. Added 11 two API tests to check that schemes are properly read from the 12 Info.plist and that content loaded using a specified app-bound scheme 13 has restricted API use. 14 15 * TestWebKitAPI/Info.plist: 16 * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm: 17 (TEST): 18 1 19 2020-07-02 Philippe Normand <pnormand@igalia.com> 2 20 -
trunk/Tools/TestWebKitAPI/Info.plist
r259322 r263874 5 5 <key>WKAppBoundDomains</key> 6 6 <array> 7 <string>test:</string> 8 <string>:</string> 9 <string>test:</string> 7 10 <string>testDomain1</string> 8 11 <string>apple.com</string> … … 22 25 <string>http://bar.com/</string> 23 26 <string>http://foo.com/</string> 27 <string>app-bound-custom-scheme:</string> 28 <string>should-not-be-included:</string> 24 29 </array> 25 30 <key>CFBundleName</key> -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm
r263806 r263874 29 29 #import "ServiceWorkerTCPServer.h" 30 30 #import "TestNavigationDelegate.h" 31 #import "TestURLSchemeHandler.h" 31 32 #import "TestWKWebView.h" 32 33 #import "WKWebViewConfigurationExtras.h" … … 285 286 } 286 287 288 TEST(InAppBrowserPrivacy, AppBoundSchemes) 289 { 290 initializeInAppBrowserPrivacyTestSettings(); 291 isDone = false; 292 [[WKWebsiteDataStore defaultDataStore] _appBoundSchemes:^(NSArray<NSString *> *schemes) { 293 NSArray *schemesToCompare = @[@"app-bound-custom-scheme", @"test"]; 294 295 NSArray *sortedSchemes = [schemes sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 296 297 int length = [sortedSchemes count]; 298 EXPECT_EQ(length, 2); 299 for (int i = 0; i < length; i++) 300 EXPECT_WK_STREQ([sortedSchemes objectAtIndex:i], [schemesToCompare objectAtIndex:i]); 301 302 cleanUpInAppBrowserPrivacyTestSettings(); 303 isDone = true; 304 }]; 305 TestWebKitAPI::Util::run(&isDone); 306 } 307 287 308 TEST(InAppBrowserPrivacy, LocalFilesAreAppBound) 288 309 { … … 1273 1294 } 1274 1295 1296 TEST(InAppBrowserPrivacy, AppBoundCustomScheme) 1297 { 1298 initializeInAppBrowserPrivacyTestSettings(); 1299 isDone = false; 1300 1301 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 1302 auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]); 1303 [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"test"]; 1304 [configuration setLimitsNavigationsToAppBoundDomains:YES]; 1305 1306 [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) { 1307 auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil]); 1308 [task didReceiveResponse:response.get()]; 1309 [task didReceiveData:[NSData dataWithBytes:mainBytes length:strlen(mainBytes)]]; 1310 [task didFinish]; 1311 }]; 1312 1313 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 1314 1315 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"test://host/main.html"]]; 1316 1317 [webView loadRequest:request]; 1318 [webView _test_waitForDidFinishNavigation]; 1319 1320 isDone = false; 1321 [webView _isNavigatingToAppBoundDomain:^(BOOL isAppBound) { 1322 EXPECT_TRUE(isAppBound); 1323 cleanUpInAppBrowserPrivacyTestSettings(); 1324 isDone = true; 1325 }]; 1326 TestWebKitAPI::Util::run(&isDone); 1327 1328 // Make sure app-bound behavior works for this webview. 1329 isDone = false; 1330 [webView evaluateJavaScript:@"location.href;" completionHandler:^(id result, NSError *error) { 1331 EXPECT_TRUE([result isKindOfClass:[NSString class]]); 1332 EXPECT_FALSE(!!error); 1333 EXPECT_TRUE([result isEqualToString:@"test://host/main.html"]); 1334 1335 isDone = true; 1336 }]; 1337 1338 TestWebKitAPI::Util::run(&isDone); 1339 } 1340 1275 1341 #endif // USE(APPLE_INTERNAL_SDK) 1276 1342
Note:
See TracChangeset
for help on using the changeset viewer.