- Revision
- 243753
- Author
- [email protected]
- Date
- 2019-04-02 12:46:30 -0700 (Tue, 02 Apr 2019)
Log Message
REGRESSION (r243726): Crash at unrecognized selector: -[WKWebpagePreferences webpagePreferences]
https://bugs.webkit.org/show_bug.cgi?id=196496
<rdar://problem/49521634>
Reviewed by Chris Dumez.
Source/WebKit:
r243726 made an incorrect assumption that all callers of -decidePolicyForNavigationAction:decisionHandler: and
-decidePolicyForNavigationAction:userInfo:decisionHandler: must be instances of _WKWebsitePolicies, as opposed
to the new WKWebpagePreferences. However, it's possible for clients (in this case, Safari) to already generate
and pass in an instance of WKWebpagePreferences by bridging the C API opaque ref (WKWebsitePoliciesRef) into the
Objective-C object (which is now WKWebpagePreferences, after my change).
To maintain binary compatibility of trunk WebKit against prior versions of Safari, we need to handle both
WKWebpagePreferences and the soon-to-be-deprecated _WKWebsitePolicies in the navigation action policy decision
handler.
Tests: WebKit.WebsitePoliciesWithBridgingCast
WebKit.WebsitePoliciesWithUnexpectedType
* UIProcess/Cocoa/NavigationState.mm:
(WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction):
Tools:
Add new API tests (see WebKit ChangeLog for more detail).
* TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
(-[WebsitePoliciesNavigationDelegate _webView:decidePolicyForNavigationAction:userInfo:decisionHandler:]):
(TEST):
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (243752 => 243753)
--- trunk/Source/WebKit/ChangeLog 2019-04-02 19:43:51 UTC (rev 243752)
+++ trunk/Source/WebKit/ChangeLog 2019-04-02 19:46:30 UTC (rev 243753)
@@ -1,3 +1,27 @@
+2019-04-02 Wenson Hsieh <[email protected]>
+
+ REGRESSION (r243726): Crash at unrecognized selector: -[WKWebpagePreferences webpagePreferences]
+ https://bugs.webkit.org/show_bug.cgi?id=196496
+ <rdar://problem/49521634>
+
+ Reviewed by Chris Dumez.
+
+ r243726 made an incorrect assumption that all callers of -decidePolicyForNavigationAction:decisionHandler: and
+ -decidePolicyForNavigationAction:userInfo:decisionHandler: must be instances of _WKWebsitePolicies, as opposed
+ to the new WKWebpagePreferences. However, it's possible for clients (in this case, Safari) to already generate
+ and pass in an instance of WKWebpagePreferences by bridging the C API opaque ref (WKWebsitePoliciesRef) into the
+ Objective-C object (which is now WKWebpagePreferences, after my change).
+
+ To maintain binary compatibility of trunk WebKit against prior versions of Safari, we need to handle both
+ WKWebpagePreferences and the soon-to-be-deprecated _WKWebsitePolicies in the navigation action policy decision
+ handler.
+
+ Tests: WebKit.WebsitePoliciesWithBridgingCast
+ WebKit.WebsitePoliciesWithUnexpectedType
+
+ * UIProcess/Cocoa/NavigationState.mm:
+ (WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction):
+
2019-04-01 Chris Dumez <[email protected]>
Unreviewed, drop debug logging landed as part of r242903 by mistake.
Modified: trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm (243752 => 243753)
--- trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm 2019-04-02 19:43:51 UTC (rev 243752)
+++ trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm 2019-04-02 19:46:30 UTC (rev 243753)
@@ -552,12 +552,19 @@
auto checker = CompletionHandlerCallChecker::create(navigationDelegate.get(), delegateHasWebsitePolicies ? @selector(_webView:decidePolicyForNavigationAction:decisionHandler:) : @selector(webView:decidePolicyForNavigationAction:decisionHandler:));
- auto decisionHandlerWithPolicies = [localListener = WTFMove(listener), navigationAction = navigationAction.copyRef(), checker = WTFMove(checker), webPageProxy = makeRef(webPageProxy), subframeNavigation](WKNavigationActionPolicy actionPolicy, _WKWebsitePolicies *websitePolicies) mutable {
+ auto decisionHandlerWithPolicies = [localListener = WTFMove(listener), navigationAction = navigationAction.copyRef(), checker = WTFMove(checker), webPageProxy = makeRef(webPageProxy), subframeNavigation](WKNavigationActionPolicy actionPolicy, id policiesOrPreferences) mutable {
if (checker->completionHandlerHasBeenCalled())
return;
checker->didCallCompletionHandler();
- RefPtr<API::WebsitePolicies> apiWebsitePolicies = [websitePolicies webpagePreferences] ? [websitePolicies webpagePreferences]->_websitePolicies.get() : nullptr;
+ RefPtr<API::WebsitePolicies> apiWebsitePolicies;
+ if ([policiesOrPreferences isKindOfClass:WKWebpagePreferences.self])
+ apiWebsitePolicies = ((WKWebpagePreferences *)policiesOrPreferences)->_websitePolicies.get();
+ else if ([policiesOrPreferences isKindOfClass:_WKWebsitePolicies.self])
+ apiWebsitePolicies = [policiesOrPreferences webpagePreferences]->_websitePolicies.get();
+ else if (policiesOrPreferences)
+ [NSException raise:NSInvalidArgumentException format:@"Expected policies of class %@, but got %@", NSStringFromClass(_WKWebsitePolicies.self), [policiesOrPreferences class]];
+
if (apiWebsitePolicies) {
if (auto* websiteDataStore = apiWebsitePolicies->websiteDataStore()) {
auto sessionID = websiteDataStore->websiteDataStore().sessionID();
Modified: trunk/Tools/ChangeLog (243752 => 243753)
--- trunk/Tools/ChangeLog 2019-04-02 19:43:51 UTC (rev 243752)
+++ trunk/Tools/ChangeLog 2019-04-02 19:46:30 UTC (rev 243753)
@@ -1,3 +1,17 @@
+2019-04-02 Wenson Hsieh <[email protected]>
+
+ REGRESSION (r243726): Crash at unrecognized selector: -[WKWebpagePreferences webpagePreferences]
+ https://bugs.webkit.org/show_bug.cgi?id=196496
+ <rdar://problem/49521634>
+
+ Reviewed by Chris Dumez.
+
+ Add new API tests (see WebKit ChangeLog for more detail).
+
+ * TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
+ (-[WebsitePoliciesNavigationDelegate _webView:decidePolicyForNavigationAction:userInfo:decisionHandler:]):
+ (TEST):
+
2019-04-02 David Kilzer <[email protected]>
Rename CLANG_ADDRESS_SANITIZER Xcode variable to ENABLE_ADDRESS_SANITIZER
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm (243752 => 243753)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm 2019-04-02 19:43:51 UTC (rev 243752)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm 2019-04-02 19:46:30 UTC (rev 243753)
@@ -26,6 +26,7 @@
#include "config.h"
#import "PlatformUtilities.h"
+#import "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKPagePrivate.h>
@@ -36,6 +37,7 @@
#import <WebKit/WKUserContentControllerPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/WKWebsiteDataStorePrivate.h>
+#import <WebKit/WKWebsitePolicies.h>
#import <WebKit/_WKUserContentExtensionStorePrivate.h>
#import <WebKit/_WKWebsiteDataStoreConfiguration.h>
#import <WebKit/_WKWebsitePolicies.h>
@@ -239,6 +241,22 @@
@end
+@interface WebsitePoliciesNavigationDelegate : TestNavigationDelegate <WKNavigationDelegatePrivate>
+@property (nonatomic, copy) void (^decidePolicyForNavigationActionWithWebsitePolicies)(WKNavigationAction *, id <NSSecureCoding>, void (^)(WKNavigationActionPolicy, _WKWebsitePolicies *));
+@end
+
+@implementation WebsitePoliciesNavigationDelegate
+
+- (void)_webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction userInfo:(id <NSSecureCoding>)userInfo decisionHandler:(void (^)(WKNavigationActionPolicy, _WKWebsitePolicies *))decisionHandler
+{
+ if (_decidePolicyForNavigationActionWithWebsitePolicies)
+ _decidePolicyForNavigationActionWithWebsitePolicies(navigationAction, userInfo, decisionHandler);
+ else
+ decisionHandler(WKNavigationActionPolicyAllow, nil);
+}
+
+@end
+
TEST(WebKit, WebsitePoliciesAutoplayEnabled)
{
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -514,6 +532,46 @@
ASSERT_TRUE(*receivedAutoplayEventFlags & kWKAutoplayEventFlagsHasAudio);
}
+TEST(WebKit, WebsitePoliciesWithBridgingCast)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 336, 276) configuration:configuration.get()]);
+ auto delegate = adoptNS([[WebsitePoliciesNavigationDelegate alloc] init]);
+
+ __block bool didInvokeDecisionHandler = false;
+ [delegate setDecidePolicyForNavigationActionWithWebsitePolicies:^(WKNavigationAction *, id <NSSecureCoding>, void (^decisionHandler)(WKNavigationActionPolicy, _WKWebsitePolicies *)) {
+ auto policies = adoptWK(WKWebsitePoliciesCreate());
+ decisionHandler(WKNavigationActionPolicyAllow, (__bridge _WKWebsitePolicies *)policies.get());
+ didInvokeDecisionHandler = true;
+ }];
+
+ [webView setNavigationDelegate:delegate.get()];
+ [webView loadTestPageNamed:@"simple"];
+ [delegate waitForDidFinishNavigation];
+ EXPECT_TRUE(didInvokeDecisionHandler);
+}
+
+TEST(WebKit, WebsitePoliciesWithUnexpectedType)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 336, 276) configuration:configuration.get()]);
+ auto delegate = adoptNS([[WebsitePoliciesNavigationDelegate alloc] init]);
+
+ __block bool didCatchException = false;
+ [delegate setDecidePolicyForNavigationActionWithWebsitePolicies:^(WKNavigationAction *, id <NSSecureCoding>, void (^decisionHandler)(WKNavigationActionPolicy, _WKWebsitePolicies *)) {
+ @try {
+ id fakePolicies = @"Hello";
+ decisionHandler(WKNavigationActionPolicyAllow, (_WKWebsitePolicies *)fakePolicies);
+ } @catch (NSException *exception) {
+ didCatchException = true;
+ }
+ }];
+
+ [webView setNavigationDelegate:delegate.get()];
+ [webView loadTestPageNamed:@"simple"];
+ TestWebKitAPI::Util::run(&didCatchException);
+}
+
struct ParsedRange {
ParsedRange(String string)
{