WebKit.WebsitePoliciesAutoplayQuirks API test times out with async policy delegates
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 19 Mar 2018 22:30:57 +0000 (22:30 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 19 Mar 2018 22:30:57 +0000 (22:30 +0000)
commit69852a8f2159d5716bb49a0672fe3f282f0886be
tree55e90911db178810e0144e1747db1061cd1ce33e
parent6635b86aded5963de828c153315d1c2de709d91b
WebKit.WebsitePoliciesAutoplayQuirks API test times out with async policy delegates
https://bugs.webkit.org/show_bug.cgi?id=183702
<rdar://problem/38566060>

Reviewed by Alex Christensen.

Source/WebCore:

The issue is that the test calls loadHTMLString then loadRequest right after, without
waiting for the first load to complete first. loadHTMLString is special as it relies
on substitute data and which schedules a timer to commit the data. When doing the
navigation policy check for the following loadRequest(), the substitute data timer
would fire and commit its data and load. This would in turn cancel the pending
navigation policy check for the loadRequest().

With sync policy delegates, this is not an issue because we take care of stopping
all loaders when receiving the policy decision, which happens synchronously. However,
when the policy decision happens asynchronously, the pending substitute data load
does not get cancelled in time and it gets committed.

To address the issue, we now cancel any pending provisional load before doing the
navigation policy check.

Test: fast/loader/inner-iframe-loads-data-url-into-parent-on-unload-crash-async-delegate.html

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::clearProvisionalLoadForPolicyCheck):
* loader/FrameLoader.h:
* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy):
Cancel any pending provisional load before starting the navigation policy check. This call
needs to be here rather than in the call site of policyChecker().checkNavigationPolicy()
because there is code in PolicyChecker::checkNavigationPolicy() which relies on
FrameLoader::activeDocumentLoader().
Also, we only cancel the provisional load if there is a policy document loader. In some
rare cases (when we receive a redirect after navigation policy has been decided for the
initial request), the provisional document loader needs to receive navigation policy
decisions so we cannot clear the provisional document loader in such case.

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
(-[AsyncAutoplayPoliciesDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[AsyncAutoplayPoliciesDelegate _webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[AsyncAutoplayPoliciesDelegate _webView:handleAutoplayEvent:withFlags:]):
(TEST):

LayoutTests:

Add variant of fast/loader/inner-iframe-loads-data-url-into-parent-on-unload-crash.html with async navigation
delegate since the previous iteration of this patch broke this test case.

* fast/loader/inner-iframe-loads-data-url-into-parent-on-unload-crash-async-delegate-expected.txt: Added.
* fast/loader/inner-iframe-loads-data-url-into-parent-on-unload-crash-async-delegate.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229722 268f45cc-cd09-0410-ab3c-d52691b4dbfc
LayoutTests/ChangeLog
LayoutTests/fast/loader/inner-iframe-loads-data-url-into-parent-on-unload-crash-async-delegate-expected.txt [new file with mode: 0644]
LayoutTests/fast/loader/inner-iframe-loads-data-url-into-parent-on-unload-crash-async-delegate.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Source/WebCore/loader/PolicyChecker.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm