Changeset 203541 in webkit
- Timestamp:
- Jul 21, 2016, 5:11:14 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 4 edited
-
Source/WebKit2/ChangeLog (modified) (1 diff)
-
Source/WebKit2/UIProcess/ios/WKScrollView.mm (modified) (10 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (modified) (4 diffs)
-
Tools/TestWebKitAPI/Tests/ios/WKScrollViewDelegateCrash.mm (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r203520 r203541 1 2016-07-21 Chelsea Pugh <cpugh@apple.com> 2 3 [iOS] Apps using WKWebView will crash if they set the scroll view's delegate and don't nil it out later 4 https://bugs.webkit.org/show_bug.cgi?id=159980 5 rdar://problem/27450825 6 7 Reviewed by Dan Bernstein. 8 9 The root cause of this crash is that we are not abiding the UIScrollView API that the scroll view 10 delegate property should be weak. If setters of this delegate do not know that, since the WKWebView 11 exposes the scroll view as a UIScrollView, they may forget to nil out the delegate they set and will 12 then crash. 13 14 * UIProcess/ios/WKScrollView.mm: 15 (-[WKScrollViewDelegateForwarder methodSignatureForSelector:]): Get a RetainPtr holding the 16 external delegate and use where needed. 17 (-[WKScrollViewDelegateForwarder respondsToSelector:]): Ditto. 18 (-[WKScrollViewDelegateForwarder forwardInvocation:]): Ditto. 19 (-[WKScrollViewDelegateForwarder forwardingTargetForSelector:]): Ditto. When returning a reference 20 to the external delegate, get a retained and autoreleased reference so the caller needn't release 21 the object when done. 22 (-[WKScrollView delegate]): Ditto. 23 (-[WKScrollView _updateDelegate]): Get a RetainPtr holding the external delegate that can be 24 used throughout this method. Use the RetainPtr to get the external delegate for setting super's 25 delegate as well as creating the delegate forwarder. 26 (-[WKScrollView setDelegate:]): Get a RetainPtr holding the external delegate and use its value for 27 comparison to the object we are setting the external delegate to. 28 1 29 2016-07-21 Myles C. Maxfield <mmaxfield@apple.com> 2 30 -
trunk/Source/WebKit2/UIProcess/ios/WKScrollView.mm
r188541 r203541 30 30 31 31 #import "WKWebViewInternal.h" 32 #import "WeakObjCPtr.h" 32 33 #import <WebCore/CoreGraphicsSPI.h> 34 35 using namespace WebKit; 33 36 34 37 @interface UIScrollView (UIScrollViewInternalHack) … … 44 47 @implementation WKScrollViewDelegateForwarder { 45 48 WKWebView *_internalDelegate; 46 id <UIScrollViewDelegate> _externalDelegate;49 WeakObjCPtr<id <UIScrollViewDelegate>> _externalDelegate; 47 50 } 48 51 … … 59 62 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector 60 63 { 64 auto externalDelegate = _externalDelegate.get(); 61 65 NSMethodSignature *signature = [super methodSignatureForSelector:aSelector]; 62 66 if (!signature) 63 67 signature = [(NSObject *)_internalDelegate methodSignatureForSelector:aSelector]; 64 68 if (!signature) 65 signature = [(NSObject *) _externalDelegate methodSignatureForSelector:aSelector];69 signature = [(NSObject *)externalDelegate methodSignatureForSelector:aSelector]; 66 70 return signature; 67 71 } … … 69 73 - (BOOL)respondsToSelector:(SEL)aSelector 70 74 { 71 return [super respondsToSelector:aSelector] || [_internalDelegate respondsToSelector:aSelector] || [_externalDelegate respondsToSelector:aSelector];75 return [super respondsToSelector:aSelector] || [_internalDelegate respondsToSelector:aSelector] || [_externalDelegate.get() respondsToSelector:aSelector]; 72 76 } 73 77 74 78 - (void)forwardInvocation:(NSInvocation *)anInvocation 75 79 { 80 auto externalDelegate = _externalDelegate.get(); 76 81 SEL aSelector = [anInvocation selector]; 77 82 BOOL internalDelegateWillRespond = [_internalDelegate respondsToSelector:aSelector]; 78 BOOL externalDelegateWillRespond = [ _externalDelegate respondsToSelector:aSelector];83 BOOL externalDelegateWillRespond = [externalDelegate respondsToSelector:aSelector]; 79 84 80 85 if (internalDelegateWillRespond && externalDelegateWillRespond) … … 84 89 [anInvocation invokeWithTarget:_internalDelegate]; 85 90 if (externalDelegateWillRespond) 86 [anInvocation invokeWithTarget: _externalDelegate];91 [anInvocation invokeWithTarget:externalDelegate.get()]; 87 92 88 93 if (internalDelegateWillRespond && externalDelegateWillRespond) … … 96 101 { 97 102 BOOL internalDelegateWillRespond = [_internalDelegate respondsToSelector:aSelector]; 98 BOOL externalDelegateWillRespond = [_externalDelegate respondsToSelector:aSelector];103 BOOL externalDelegateWillRespond = [_externalDelegate.get() respondsToSelector:aSelector]; 99 104 100 105 if (internalDelegateWillRespond && !externalDelegateWillRespond) 101 106 return _internalDelegate; 102 107 if (externalDelegateWillRespond && !internalDelegateWillRespond) 103 return _externalDelegate ;108 return _externalDelegate.getAutoreleased(); 104 109 return nil; 105 110 } … … 108 113 109 114 @implementation WKScrollView { 110 id <UIScrollViewDelegate> _externalDelegate;115 WeakObjCPtr<id <UIScrollViewDelegate>> _externalDelegate; 111 116 WKScrollViewDelegateForwarder *_delegateForwarder; 112 117 } … … 133 138 - (void)setDelegate:(id <UIScrollViewDelegate>)delegate 134 139 { 135 if (_externalDelegate == delegate)140 if (_externalDelegate.get().get() == delegate) 136 141 return; 137 142 _externalDelegate = delegate; … … 141 146 - (id <UIScrollViewDelegate>)delegate 142 147 { 143 return _externalDelegate ;148 return _externalDelegate.getAutoreleased(); 144 149 } 145 150 … … 148 153 WKScrollViewDelegateForwarder *oldForwarder = _delegateForwarder; 149 154 _delegateForwarder = nil; 150 if (!_externalDelegate) 155 auto externalDelegate = _externalDelegate.get(); 156 if (!externalDelegate) 151 157 [super setDelegate:_internalDelegate]; 152 158 else if (!_internalDelegate) 153 [super setDelegate: _externalDelegate];159 [super setDelegate:externalDelegate.get()]; 154 160 else { 155 _delegateForwarder = [[WKScrollViewDelegateForwarder alloc] initWithInternalDelegate:_internalDelegate externalDelegate: _externalDelegate];161 _delegateForwarder = [[WKScrollViewDelegateForwarder alloc] initWithInternalDelegate:_internalDelegate externalDelegate:externalDelegate.get()]; 156 162 [super setDelegate:_delegateForwarder]; 157 163 } -
trunk/Tools/ChangeLog
r203540 r203541 1 2016-07-21 Chelsea Pugh <cpugh@apple.com> 2 3 [iOS] Apps using WKWebView will crash if they set the scroll view's delegate and don't nil it out later 4 https://bugs.webkit.org/show_bug.cgi?id=159980 5 rdar://problem/27450825 6 7 Reviewed by Dan Bernstein. 8 9 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 10 * TestWebKitAPI/Tests/ios/WKScrollViewDelegateCrash.mm: Added. 11 (-[TestDelegateForScrollView dealloc]): Update delegateIsDeallocated to true so that we can tell 12 when our delegate has hit -dealloc. 13 (TestWebKitAPI::TEST): Ensure that after an object has been set as the scroll view's delegate, 14 and has then been deallocated, that the scroll view's delegate is nil and the deallocated delegate 15 will not be messaged. 16 1 17 2016-07-21 Myles C. Maxfield <mmaxfield@apple.com> 2 18 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r203508 r203541 115 115 5C9E59421D3EB5AC00E3C62E /* ApplicationCache.db-shm in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */; }; 116 116 5C9E59431D3EB5AC00E3C62E /* ApplicationCache.db-wal in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */; }; 117 5E4B1D2E1D404C6100053621 /* WKScrollViewDelegateCrash.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E4B1D2C1D404C6100053621 /* WKScrollViewDelegateCrash.mm */; }; 117 118 764322D71B61CCC30024F801 /* WordBoundaryTypingAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 764322D51B61CCA40024F801 /* WordBoundaryTypingAttributes.mm */; }; 118 119 7673499D1930C5BB00E44DF9 /* StopLoadingDuringDidFailProvisionalLoad_bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7673499A1930182E00E44DF9 /* StopLoadingDuringDidFailProvisionalLoad_bundle.cpp */; }; … … 804 805 5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ApplicationCache.db-shm"; sourceTree = "<group>"; }; 805 806 5C9E59401D3EB1DE00E3C62E /* ApplicationCache.db-wal */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ApplicationCache.db-wal"; sourceTree = "<group>"; }; 807 5E4B1D2C1D404C6100053621 /* WKScrollViewDelegateCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKScrollViewDelegateCrash.mm; path = ../ios/WKScrollViewDelegateCrash.mm; sourceTree = "<group>"; }; 806 808 7560917719259C59009EF06E /* MemoryCacheAddImageToCacheIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MemoryCacheAddImageToCacheIOS.mm; sourceTree = "<group>"; }; 807 809 75F3133F18C171B70041CAEC /* EphemeralSessionPushStateNoHistoryCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EphemeralSessionPushStateNoHistoryCallback.cpp; sourceTree = "<group>"; }; … … 1248 1250 93E943F11CD3E87E00AC08C2 /* VideoControlsManager.mm */, 1249 1251 2D00065D1C1F58940088E6A7 /* WKPDFViewResizeCrash.mm */, 1252 5E4B1D2C1D404C6100053621 /* WKScrollViewDelegateCrash.mm */, 1250 1253 7C417F311D19E14800B8EF53 /* WKWebViewDefaultNavigationDelegate.mm */, 1251 1254 0F3B94A51A77266C00DE3272 /* WKWebViewEvaluateJavaScript.mm */, … … 2133 2136 7CCE7EE01A411A9A00447C4C /* EditorCommands.mm in Sources */, 2134 2137 7CCE7EBF1A411A7E00447C4C /* ElementAtPointInWebFrame.mm in Sources */, 2138 5E4B1D2E1D404C6100053621 /* WKScrollViewDelegateCrash.mm in Sources */, 2135 2139 7CCE7EEF1A411AE600447C4C /* EphemeralSessionPushStateNoHistoryCallback.cpp in Sources */, 2136 2140 7CCE7EF01A411AE600447C4C /* EvaluateJavaScript.cpp in Sources */,
Note:
See TracChangeset
for help on using the changeset viewer.