Modified: trunk/Source/WebKit2/ChangeLog (219138 => 219139)
--- trunk/Source/WebKit2/ChangeLog 2017-07-05 18:01:45 UTC (rev 219138)
+++ trunk/Source/WebKit2/ChangeLog 2017-07-05 18:08:32 UTC (rev 219139)
@@ -1,3 +1,35 @@
+2017-07-05 Andy Estes <aes...@apple.com>
+
+ [iOS] WKActionSheetAssistants can outlive their host views
+ https://bugs.webkit.org/show_bug.cgi?id=174160
+ <rdar://problem/20638607>
+
+ Reviewed by Tim Horton.
+
+ WKActionSheetAssistant keeps a raw pointer to its host UIView, and nothing clears it when
+ the host view is deallocated. If the assistant outlives the view, we can end up accessing a
+ pointer to a deallocated UIView and crashing.
+
+ I don't know how to reproduce such a crash, but this patch guards against it by doing the
+ following:
+
+ 1. Make _view a WeakObjCPtr in WKActionSheetAssistant to ensure it gets set to nil when the
+ UIView is deallocated.
+ 2. Call -[WKActionSheetAssistant cleanupSheet] when a WKContentView or WKPDFView is
+ deallocated, or when the Web process crashes. This will ensure the action sheet is
+ dismissed and prevent the user from tapping on an action that's no longer valid.
+
+ * UIProcess/ios/WKActionSheetAssistant.mm:
+ (-[WKActionSheetAssistant superviewForSheet]):
+ (-[WKActionSheetAssistant _presentationRectForSheetGivenPoint:inHostView:]):
+ (-[WKActionSheetAssistant presentationRectForElementUsingClosestIndicatedRect]):
+ (-[WKActionSheetAssistant presentationRectForIndicatedElement]):
+ (-[WKActionSheetAssistant _shouldPresentAtTouchLocationForElementRect:]):
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView cleanupInteraction]):
+ * UIProcess/ios/WKPDFView.mm:
+ (-[WKPDFView dealloc]):
+
2017-07-05 Frederic Wang <fw...@igalia.com>
Move ScrolledContentsLayer property to ScrollingStateScrollingNode
Modified: trunk/Source/WebKit2/UIProcess/ios/WKActionSheetAssistant.mm (219138 => 219139)
--- trunk/Source/WebKit2/UIProcess/ios/WKActionSheetAssistant.mm 2017-07-05 18:01:45 UTC (rev 219138)
+++ trunk/Source/WebKit2/UIProcess/ios/WKActionSheetAssistant.mm 2017-07-05 18:08:32 UTC (rev 219139)
@@ -89,7 +89,7 @@
RetainPtr<WKActionSheet> _interactionSheet;
RetainPtr<_WKActivatedElementInfo> _elementInfo;
std::optional<WebKit::InteractionInformationAtPosition> _positionInformation;
- UIView *_view;
+ WeakObjCPtr<UIView> _view;
BOOL _needsLinkIndicator;
BOOL _isPresentingDDUserInterface;
BOOL _hasPendingActionSheet;
@@ -130,7 +130,8 @@
- (UIView *)superviewForSheet
{
- UIView *view = [_view window];
+ UIView *view = _view.getAutoreleased();
+ UIView *superview = [view window];
// FIXME: WebKit has a delegate to retrieve the superview for the image sheet (superviewForImageSheetForWebView)
// Do we need it in WK2?
@@ -137,7 +138,7 @@
// Find the top most view with a view controller
UIViewController *controller = nil;
- UIView *currentView = _view;
+ UIView *currentView = view;
while (currentView) {
UIViewController *aController = [UIViewController viewControllerForView:currentView];
if (aController)
@@ -146,14 +147,14 @@
currentView = [currentView superview];
}
if (controller)
- view = controller.view;
+ superview = controller.view;
- return view;
+ return superview;
}
- (CGRect)_presentationRectForSheetGivenPoint:(CGPoint)point inHostView:(UIView *)hostView
{
- CGPoint presentationPoint = [hostView convertPoint:point fromView:_view];
+ CGPoint presentationPoint = [hostView convertPoint:point fromView:_view.getAutoreleased()];
CGRect presentationRect = CGRectMake(presentationPoint.x, presentationPoint.y, 1.0, 1.0);
return CGRectInset(presentationRect, -22.0, -22.0);
@@ -189,7 +190,7 @@
for (auto path : WebCore::PathUtilities::pathsWithShrinkWrappedRects(indicatedRects, 0)) {
auto boundingRect = path.fastBoundingRect();
if (boundingRect.contains(touchLocation))
- return CGRectInset([view convertRect:(CGRect)boundingRect fromView:_view], -presentationElementRectPadding, -presentationElementRectPadding);
+ return CGRectInset([view convertRect:(CGRect)boundingRect fromView:_view.getAutoreleased()], -presentationElementRectPadding, -presentationElementRectPadding);
}
return CGRectZero;
@@ -203,7 +204,7 @@
return CGRectZero;
auto elementBounds = _positionInformation->bounds;
- return CGRectInset([view convertRect:elementBounds fromView:_view], -presentationElementRectPadding, -presentationElementRectPadding);
+ return CGRectInset([view convertRect:elementBounds fromView:_view.getAutoreleased()], -presentationElementRectPadding, -presentationElementRectPadding);
}
- (CGRect)initialPresentationRectInHostViewForSheet
@@ -394,8 +395,9 @@
- (BOOL)_shouldPresentAtTouchLocationForElementRect:(CGRect)elementRect
{
- auto apparentElementRect = [_view convertRect:elementRect toView:_view.window];
- auto windowRect = _view.window.bounds;
+ UIView *view = _view.getAutoreleased();
+ auto apparentElementRect = [view convertRect:elementRect toView:view.window];
+ auto windowRect = view.window.bounds;
apparentElementRect = CGRectIntersection(apparentElementRect, windowRect);
auto leftInset = CGRectGetMinX(apparentElementRect) - CGRectGetMinX(windowRect);
Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (219138 => 219139)
--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm 2017-07-05 18:01:45 UTC (rev 219138)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm 2017-07-05 18:08:32 UTC (rev 219139)
@@ -602,7 +602,10 @@
{
_webSelectionAssistant = nil;
_textSelectionAssistant = nil;
+
+ [_actionSheetAssistant cleanupSheet];
_actionSheetAssistant = nil;
+
_smartMagnificationController = nil;
_didAccessoryTabInitiateFocus = NO;
_isExpectingFastSingleTapCommit = NO;
Modified: trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm (219138 => 219139)
--- trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm 2017-07-05 18:01:45 UTC (rev 219138)
+++ trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm 2017-07-05 18:08:32 UTC (rev 219139)
@@ -142,6 +142,7 @@
[self _clearPages];
[_pageNumberIndicator removeFromSuperview];
dispatch_release(_findQueue);
+ [_actionSheetAssistant cleanupSheet];
[super dealloc];
}