WebKitLegacy: Can trigger recursive loads triggering debug assertions
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Jun 2018 22:56:29 +0000 (22:56 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Jun 2018 22:56:29 +0000 (22:56 +0000)
commit5d9697e57d54e6ff47a716116b9c18d0fa4ecc69
tree4b9ee337051434f43f301fd3b43da45ed6af21f2
parent0c37c21c616de25e03ae8db40b4aaa88b78c71c9
WebKitLegacy: Can trigger recursive loads triggering debug assertions
https://bugs.webkit.org/show_bug.cgi?id=187121
<rdar://problem/41259430>

Reviewed by Brent Fulgham.

Source/WebCore:

In order to support asynchronous policy delegates, r229722 added a call to
FrameLoader::clearProvisionalLoadForPolicyCheck() when starting a navigation
policy decision in PolicyChecker::checkNavigationPolicy(). This calls
stopLoading() on the current provisional loader if there is one, and potentially
calls the didFailProvisionalLoadWithError cleint delegate. This delegate call
is synchronous on WebKit1, so the client may start a new load from this delegate
and re-enter Webcore. This happens in practive with Quickens 2017 / 2018 on Mac.

Before r229722, this was not an issue because pending loads were canceled after
the (asynchronous) navigation policy decision, via FrameLoader::stopAllLoaders().
FrameLoader::stopAllLoaders() sets a m_inStopAllLoaders flag and we return early
in FrameLoader::loadRequest() when this flag is set to prevent recursive loads.

To maintain shipping behavior as much as possible, this patch introduces a similar
inClearProvisionalLoadForPolicyCheck which gets set during
FrameLoader::clearProvisionalLoadForPolicyCheck() and we prevent new loads while
this flag is set.

I have verified that Quickens 2017 / 2018 works again after this change and I added
API test coverage for this behavior.

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::load):
(WebCore::FrameLoader::clearProvisionalLoadForPolicyCheck):
* loader/FrameLoader.h:

Tools:

Add API test coverage.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/mac/StartLoadInDidFailProvisionalLoad.mm: Added.
(-[StartLoadInDidFailProvisionalLoadDelegate webView:didFailProvisionalLoadWithError:forFrame:]):
(-[StartLoadInDidFailProvisionalLoadDelegate webView:didFinishLoadForFrame:]):
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233374 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/WebCore/ChangeLog
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/mac/StartLoadInDidFailProvisionalLoad.mm [new file with mode: 0644]