Changeset 247851 in webkit
- Timestamp:
- Jul 25, 2019 6:26:24 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r247842 r247851 1 2019-07-25 Jiewen Tan <jiewen_tan@apple.com> 2 3 WebPageProxy::receivedPolicyDecision should check navigation ID before clear pendingAPIRequest 4 https://bugs.webkit.org/show_bug.cgi?id=200108 5 <rdar://problem/53521238> 6 7 Reviewed by Chris Dumez. 8 9 Assuming there are two loads happening one after another. There is an issue when clients save 10 the first decisionHandler and then call WKNavigationActionPolicyCancel for it right after the 11 second decisionHandler received, -[WKWebView URL] could return a null string even though it is 12 loading the second one. 13 14 To solve that, this patch pairs a navigationID with the pendingAPIRequestURL such that 15 WebPageProxy::receivedPolicyDecision could clear the pendingAPIRequestURL only if 16 the passed navigation ID matches the current one. 17 18 * UIProcess/PageLoadState.cpp: 19 (WebKit::PageLoadState::reset): 20 (WebKit::PageLoadState::activeURL): 21 (WebKit::PageLoadState::estimatedProgress): 22 (WebKit::PageLoadState::pendingAPIRequestURL const): 23 (WebKit::PageLoadState::pendingAPIRequest const): 24 (WebKit::PageLoadState::setPendingAPIRequest): 25 (WebKit::PageLoadState::clearPendingAPIRequest): 26 (WebKit::PageLoadState::isLoading): 27 (WebKit::PageLoadState::setPendingAPIRequestURL): Deleted. 28 (WebKit::PageLoadState::clearPendingAPIRequestURL): Deleted. 29 * UIProcess/PageLoadState.h: 30 (WebKit::PageLoadState::setPendingAPIRequest): 31 (WebKit::PageLoadState::setPendingAPIRequestURL): Deleted. 32 * UIProcess/WebPageProxy.cpp: 33 (WebKit::WebPageProxy::launchProcessForReload): 34 (WebKit::WebPageProxy::loadRequestWithNavigationShared): 35 (WebKit::WebPageProxy::loadFile): 36 (WebKit::WebPageProxy::loadDataWithNavigationShared): 37 (WebKit::WebPageProxy::loadAlternateHTML): 38 (WebKit::WebPageProxy::loadWebArchiveData): 39 (WebKit::WebPageProxy::reload): 40 (WebKit::WebPageProxy::goToBackForwardItem): 41 (WebKit::WebPageProxy::receivedPolicyDecision): 42 (WebKit::WebPageProxy::continueNavigationInNewProcess): 43 (WebKit::WebPageProxy::didStartProvisionalLoadForFrameShared): 44 (WebKit::WebPageProxy::didSameDocumentNavigationForFrame): 45 (WebKit::WebPageProxy::decidePolicyForNavigationAction): 46 1 47 2019-07-25 Commit Queue <commit-queue@webkit.org> 2 48 -
trunk/Source/WebKit/UIProcess/PageLoadState.cpp
r246694 r247851 155 155 m_uncommittedState.hasInsecureContent = false; 156 156 157 m_uncommittedState.pendingAPIRequest URL = String();157 m_uncommittedState.pendingAPIRequest = { }; 158 158 m_uncommittedState.provisionalURL = String(); 159 159 m_uncommittedState.url = String(); … … 183 183 // even when there's no main frame yet, as it might be the 184 184 // first API request. 185 if (!data.pendingAPIRequest URL.isNull())186 return data.pendingAPIRequest URL;185 if (!data.pendingAPIRequest.url.isNull()) 186 return data.pendingAPIRequest.url; 187 187 188 188 if (!data.unreachableURL.isEmpty()) … … 224 224 double PageLoadState::estimatedProgress(const Data& data) 225 225 { 226 if (!data.pendingAPIRequest URL.isNull())226 if (!data.pendingAPIRequest.url.isNull()) 227 227 return initialProgressValue; 228 228 … … 237 237 const String& PageLoadState::pendingAPIRequestURL() const 238 238 { 239 return m_committedState.pendingAPIRequestURL; 239 return m_committedState.pendingAPIRequest.url; 240 } 241 242 auto PageLoadState::pendingAPIRequest() const -> const PendingAPIRequest& 243 { 244 return m_committedState.pendingAPIRequest; 240 245 } 241 246 … … 245 250 } 246 251 247 void PageLoadState::setPendingAPIRequest URL(const Transaction::Token& token, const String& pendingAPIRequestURL, const URL& resourceDirectoryURL)248 { 249 ASSERT_UNUSED(token, &token.m_pageLoadState == this); 250 m_uncommittedState.pendingAPIRequest URL = pendingAPIRequestURL;252 void PageLoadState::setPendingAPIRequest(const Transaction::Token& token, PendingAPIRequest&& pendingAPIRequest, const URL& resourceDirectoryURL) 253 { 254 ASSERT_UNUSED(token, &token.m_pageLoadState == this); 255 m_uncommittedState.pendingAPIRequest = WTFMove(pendingAPIRequest); 251 256 m_uncommittedState.resourceDirectoryURL = resourceDirectoryURL; 252 257 } 253 258 254 void PageLoadState::clearPendingAPIRequest URL(const Transaction::Token& token)255 { 256 ASSERT_UNUSED(token, &token.m_pageLoadState == this); 257 m_uncommittedState.pendingAPIRequest URL = String();259 void PageLoadState::clearPendingAPIRequest(const Transaction::Token& token) 260 { 261 ASSERT_UNUSED(token, &token.m_pageLoadState == this); 262 m_uncommittedState.pendingAPIRequest = { }; 258 263 } 259 264 … … 411 416 bool PageLoadState::isLoading(const Data& data) 412 417 { 413 if (!data.pendingAPIRequest URL.isNull())418 if (!data.pendingAPIRequest.url.isNull()) 414 419 return true; 415 420 -
trunk/Source/WebKit/UIProcess/PageLoadState.h
r246694 r247851 114 114 }; 115 115 116 struct PendingAPIRequest { 117 uint64_t navigationID { 0 }; 118 String url; 119 }; 120 116 121 void addObserver(Observer&); 117 122 void removeObserver(Observer&); … … 145 150 146 151 const String& pendingAPIRequestURL() const; 147 void setPendingAPIRequestURL(const Transaction::Token&, const String& pendingAPIRequestURL, const URL& resourceDirectoryPath = { }); 148 void clearPendingAPIRequestURL(const Transaction::Token&); 152 const PendingAPIRequest& pendingAPIRequest() const; 153 void setPendingAPIRequest(const Transaction::Token&, PendingAPIRequest&& pendingAPIRequest, const URL& resourceDirectoryPath = { }); 154 void clearPendingAPIRequest(const Transaction::Token&); 149 155 150 156 void didStartProvisionalLoad(const Transaction::Token&, const String& url, const String& unreachableURL); … … 208 214 bool hasInsecureContent; 209 215 210 String pendingAPIRequestURL;216 PendingAPIRequest pendingAPIRequest; 211 217 212 218 String provisionalURL; -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r247820 r247851 889 889 auto navigation = m_navigationState->createReloadNavigation(); 890 890 891 String url = currentURL(); 892 if (!url.isEmpty()) { 893 auto transaction = m_pageLoadState.transaction(); 894 m_pageLoadState.setPendingAPIRequest(transaction, { navigation->navigationID(), url }); 895 } 896 891 897 // We allow stale content when reloading a WebProcess that's been killed or crashed. 892 898 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), m_backForwardList->currentItem()->itemID(), FrameLoadType::IndexedBackForward, ShouldTreatAsContinuingLoad::No, WTF::nullopt), m_pageID); … … 1116 1122 auto url = request.url(); 1117 1123 if (shouldTreatAsContinuingLoad != ShouldTreatAsContinuingLoad::Yes) 1118 m_pageLoadState.setPendingAPIRequest URL(transaction, url);1124 m_pageLoadState.setPendingAPIRequest(transaction, { navigation.navigationID(), url }); 1119 1125 1120 1126 LoadParameters loadParameters; … … 1169 1175 auto transaction = m_pageLoadState.transaction(); 1170 1176 1171 m_pageLoadState.setPendingAPIRequest URL(transaction, fileURLString, resourceDirectoryURL);1177 m_pageLoadState.setPendingAPIRequest(transaction, { navigation->navigationID(), fileURLString }, resourceDirectoryURL); 1172 1178 1173 1179 String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath(); … … 1213 1219 auto transaction = m_pageLoadState.transaction(); 1214 1220 1215 m_pageLoadState.setPendingAPIRequest URL(transaction, !baseURL.isEmpty() ? baseURL : WTF::blankURL().string());1221 m_pageLoadState.setPendingAPIRequest(transaction, { navigation.navigationID(), !baseURL.isEmpty() ? baseURL : WTF::blankURL().string() }); 1216 1222 1217 1223 LoadParameters loadParameters; … … 1252 1258 auto transaction = m_pageLoadState.transaction(); 1253 1259 1254 m_pageLoadState.setPendingAPIRequest URL(transaction, unreachableURL);1260 m_pageLoadState.setPendingAPIRequest(transaction, { 0, unreachableURL }); 1255 1261 m_pageLoadState.setUnreachableURL(transaction, unreachableURL); 1256 1262 … … 1288 1294 1289 1295 auto transaction = m_pageLoadState.transaction(); 1290 m_pageLoadState.setPendingAPIRequest URL(transaction, WTF::blankURL().string());1296 m_pageLoadState.setPendingAPIRequest(transaction, { 0, WTF::blankURL().string() }); 1291 1297 1292 1298 LoadParameters loadParameters; … … 1346 1352 String url = currentURL(); 1347 1353 if (!url.isEmpty()) { 1348 auto transaction = m_pageLoadState.transaction();1349 m_pageLoadState.setPendingAPIRequestURL(transaction, url);1350 1351 1354 // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch 1352 1355 maybeInitializeSandboxExtensionHandle(m_process, URL(URL(), url), currentResourceDirectoryURL(), sandboxExtensionHandle); … … 1357 1360 1358 1361 auto navigation = m_navigationState->createReloadNavigation(); 1362 1363 if (!url.isEmpty()) { 1364 auto transaction = m_pageLoadState.transaction(); 1365 m_pageLoadState.setPendingAPIRequest(transaction, { navigation->navigationID(), url }); 1366 } 1359 1367 1360 1368 // Store decision to reload without content blockers on the navigation so that we can later set the corresponding … … 1425 1433 return launchProcessWithItem(item); 1426 1434 1427 auto transaction = m_pageLoadState.transaction();1428 1429 m_pageLoadState.setPendingAPIRequestURL(transaction, item.url());1430 1431 1435 RefPtr<API::Navigation> navigation; 1432 1436 if (!m_backForwardList->currentItem()->itemIsInSameDocument(item)) 1433 1437 navigation = m_navigationState->createBackForwardNavigation(item, m_backForwardList->currentItem(), frameLoadType); 1438 1439 auto transaction = m_pageLoadState.transaction(); 1440 m_pageLoadState.setPendingAPIRequest(transaction, { navigation ? navigation->navigationID() : 0, item.url() }); 1434 1441 1435 1442 m_process->send(Messages::WebPage::GoToBackForwardItem(navigation ? navigation->navigationID() : 0, item.itemID(), frameLoadType, ShouldTreatAsContinuingLoad::No, WTF::nullopt), m_pageID); … … 2878 2885 auto transaction = m_pageLoadState.transaction(); 2879 2886 2880 if (action == PolicyAction::Ignore && willContinueLoadInNewProcess == WillContinueLoadInNewProcess::No )2881 m_pageLoadState.clearPendingAPIRequest URL(transaction);2887 if (action == PolicyAction::Ignore && willContinueLoadInNewProcess == WillContinueLoadInNewProcess::No && navigation && navigation->navigationID() == m_pageLoadState.pendingAPIRequest().navigationID) 2888 m_pageLoadState.clearPendingAPIRequest(transaction); 2882 2889 2883 2890 DownloadID downloadID = { }; … … 2957 2964 2958 2965 auto transaction = m_pageLoadState.transaction(); 2959 m_pageLoadState.setPendingAPIRequest URL(transaction, item->url());2966 m_pageLoadState.setPendingAPIRequest(transaction, { navigation.navigationID(), item->url() }); 2960 2967 2961 2968 m_provisionalPage->goToBackForwardItem(navigation, *item, WTFMove(websitePolicies)); … … 3977 3984 auto transaction = m_pageLoadState.transaction(); 3978 3985 3979 m_pageLoadState.clearPendingAPIRequest URL(transaction);3986 m_pageLoadState.clearPendingAPIRequest(transaction); 3980 3987 3981 3988 if (frame->isMainFrame()) { … … 4442 4449 } 4443 4450 4444 m_pageLoadState.clearPendingAPIRequest URL(transaction);4451 m_pageLoadState.clearPendingAPIRequest(transaction); 4445 4452 frame->didSameDocumentNavigation(url); 4446 4453 … … 4624 4631 auto transaction = m_pageLoadState.transaction(); 4625 4632 4626 bool fromAPI = request.url() == m_pageLoadState.pendingAPIRequestURL();4633 bool fromAPI = navigationID == m_pageLoadState.pendingAPIRequest().navigationID; 4627 4634 if (!fromAPI) 4628 m_pageLoadState.clearPendingAPIRequest URL(transaction);4635 m_pageLoadState.clearPendingAPIRequest(transaction); 4629 4636 4630 4637 if (!checkURLReceivedFromCurrentOrPreviousWebProcess(process, request.url())) { … … 4685 4692 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) mutable { 4686 4693 4687 auto completionHandler = [this, protectedThis = protectedThis.copyRef(), frame = frame.copyRef(), sender = WTFMove(sender), navigation = WTFMove(navigation), processSwapRequestedByClient, policies = makeRefPtr(policies)] (PolicyAction policyAction) mutable {4694 auto completionHandler = [this, protectedThis = protectedThis.copyRef(), frame = frame.copyRef(), sender = WTFMove(sender), navigation, processSwapRequestedByClient, policies = makeRefPtr(policies)] (PolicyAction policyAction) mutable { 4688 4695 if (frame->isMainFrame()) { 4689 4696 if (!policies) { … … 4705 4712 if (frame->isMainFrame() && safeBrowsingWarning->url().isValid()) { 4706 4713 auto transaction = m_pageLoadState.transaction(); 4707 m_pageLoadState.setPendingAPIRequest URL(transaction, safeBrowsingWarning->url());4714 m_pageLoadState.setPendingAPIRequest(transaction, { navigation->navigationID(), safeBrowsingWarning->url() }); 4708 4715 m_pageLoadState.commitChanges(); 4709 4716 } -
trunk/Tools/ChangeLog
r247850 r247851 1 2019-07-24 Jiewen Tan <jiewen_tan@apple.com> 2 3 WebPageProxy::receivedPolicyDecision should check navigation ID before clear pendingAPIRequest 4 https://bugs.webkit.org/show_bug.cgi?id=200108 5 <rdar://problem/53521238> 6 7 Reviewed by Chris Dumez. 8 9 Added an API test. 10 11 * TestWebKitAPI/Tests/WebKitCocoa/DecidePolicyForNavigationAction.mm: 12 (-[DecidePolicyForNavigationActionController webView:decidePolicyForNavigationAction:decisionHandler:]): 13 (TEST): 14 1 15 2019-07-25 Jonathan Bedard <jbedard@apple.com> 2 16 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DecidePolicyForNavigationAction.mm
r242339 r247851 33 33 #import <WebKit/WKProcessPoolPrivate.h> 34 34 #import <WebKit/_WKProcessPoolConfiguration.h> 35 #import <wtf/BlockPtr.h> 35 36 #import <wtf/RetainPtr.h> 36 37 #import <wtf/mac/AppKitCompatibilityDeclarations.h> 37 38 38 39 static bool shouldCancelNavigation; 40 static bool shouldDelayDecision; 39 41 static bool createdWebView; 40 42 static bool decidedPolicy; … … 42 44 static RetainPtr<WKNavigationAction> action; 43 45 static RetainPtr<WKWebView> newWebView; 46 static BlockPtr<void(WKNavigationActionPolicy)> delayedDecision; 44 47 45 48 static NSString *firstURL = @"data:text/html,First"; … … 63 66 } 64 67 68 if (shouldDelayDecision) { 69 if (delayedDecision) 70 delayedDecision(WKNavigationActionPolicyCancel); 71 delayedDecision = makeBlockPtr(decisionHandler); 72 decidedPolicy = true; 73 return; 74 } 75 65 76 decisionHandler(webView == newWebView.get() ? WKNavigationActionPolicyCancel : WKNavigationActionPolicyAllow); 66 77 … … 592 603 newWebView = nullptr; 593 604 action = nullptr; 605 } 606 607 TEST(WebKit, DelayDecidePolicyForNavigationAction) 608 { 609 shouldDelayDecision = true; 610 611 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]); 612 auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]); 613 [webView setNavigationDelegate:controller.get()]; 614 615 RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]; 616 [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]]; 617 TestWebKitAPI::Util::run(&decidedPolicy); 618 [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]]; 619 TestWebKitAPI::Util::sleep(0.5); // Wait until the pending api request gets clear. 620 EXPECT_TRUE([[webView URL] isEqual:testURL.get()]); 621 622 shouldDelayDecision = false; 623 delayedDecision(WKNavigationActionPolicyCancel); 594 624 } 595 625
Note: See TracChangeset
for help on using the changeset viewer.