Title: [196267] trunk/Source/WebKit/mac
Revision
196267
Author
ander...@apple.com
Date
2016-02-08 12:53:21 -0800 (Mon, 08 Feb 2016)

Log Message

Crash when trying to chain to the old -[NSView setNeedsDisplayInRect:]
https://bugs.webkit.org/show_bug.cgi?id=154001
rdar://problem/24519975

Reviewed by Dan Bernstein.

If our replaced -[NSView setNeedsDisplayInRect:] is called before the old IMP has been initialized,
we can end up trying to call a null pointer.

Fix this by using method_exchangeImplementations instead of method_setImplementation, since the former is done
atomically.

* WebView/WebHTMLView.mm:
(-[NSView _web_setNeedsDisplayInRect:]):
(+[WebHTMLViewPrivate initialize]):
(setNeedsDisplayInRect): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebKit/mac/ChangeLog (196266 => 196267)


--- trunk/Source/WebKit/mac/ChangeLog	2016-02-08 19:49:52 UTC (rev 196266)
+++ trunk/Source/WebKit/mac/ChangeLog	2016-02-08 20:53:21 UTC (rev 196267)
@@ -1,3 +1,22 @@
+2016-02-08  Anders Carlsson  <ander...@apple.com>
+
+        Crash when trying to chain to the old -[NSView setNeedsDisplayInRect:]
+        https://bugs.webkit.org/show_bug.cgi?id=154001
+        rdar://problem/24519975
+
+        Reviewed by Dan Bernstein.
+
+        If our replaced -[NSView setNeedsDisplayInRect:] is called before the old IMP has been initialized,
+        we can end up trying to call a null pointer. 
+        
+        Fix this by using method_exchangeImplementations instead of method_setImplementation, since the former is done
+        atomically.
+
+        * WebView/WebHTMLView.mm:
+        (-[NSView _web_setNeedsDisplayInRect:]):
+        (+[WebHTMLViewPrivate initialize]):
+        (setNeedsDisplayInRect): Deleted.
+
 2016-02-07  Dan Bernstein  <m...@apple.com>
 
         [Cocoa] Replace __has_include guards around inclusion of Apple-internal-SDK headers with USE(APPLE_INTERNAL_SDK)

Modified: trunk/Source/WebKit/mac/WebView/WebHTMLView.mm (196266 => 196267)


--- trunk/Source/WebKit/mac/WebView/WebHTMLView.mm	2016-02-08 19:49:52 UTC (rev 196266)
+++ trunk/Source/WebKit/mac/WebView/WebHTMLView.mm	2016-02-08 20:53:21 UTC (rev 196267)
@@ -688,12 +688,20 @@
 @end
 
 #if !PLATFORM(IOS)
-static IMP oldSetNeedsDisplayInRectIMP;
 
-static void setNeedsDisplayInRect(NSView *self, SEL cmd, NSRect invalidRect)
+@interface NSView (WebSetNeedsDisplayInRect)
+- (void)_web_setNeedsDisplayInRect:(NSRect)invalidRect;
+@end
+
+@implementation NSView (WebSetNeedsDisplayInRect)
+
+- (void)_web_setNeedsDisplayInRect:(NSRect)invalidRect
 {
+    // Note that we call method_exchangeImplementations below, so any calls
+    // to _web_setNeedsDisplayInRect: will actually call -[NSView setNeedsDisplayInRect:].
+
     if (![NSThread isMainThread] || ![self _drawnByAncestor]) {
-        wtfCallIMP<id>(oldSetNeedsDisplayInRectIMP, self, cmd, invalidRect);
+        [self _web_setNeedsDisplayInRect:invalidRect];
         return;
     }
 
@@ -703,14 +711,14 @@
         enclosingWebFrameView = (WebFrameView *)[enclosingWebFrameView superview];
 
     if (!enclosingWebFrameView) {
-        wtfCallIMP<id>(oldSetNeedsDisplayInRectIMP, self, cmd, invalidRect);
+        [self _web_setNeedsDisplayInRect:invalidRect];
         return;
     }
 
     Frame* coreFrame = core([enclosingWebFrameView webFrame]);
     FrameView* frameView = coreFrame ? coreFrame->view() : 0;
     if (!frameView || !frameView->isEnclosedInCompositingLayer()) {
-        wtfCallIMP<id>(oldSetNeedsDisplayInRectIMP, self, cmd, invalidRect);
+        [self _web_setNeedsDisplayInRect:invalidRect];
         return;
     }
 
@@ -722,6 +730,8 @@
     frameView->invalidateRect(invalidRectInFrameViewCoordinates);
 }
 
+@end
+
 @interface NSApplication (WebNSApplicationDetails)
 - (void)speakString:(NSString *)string;
 @end
@@ -1026,15 +1036,8 @@
         ASSERT(oldSetCursorForMouseLocationIMP);
     }
 
-    if (!oldSetNeedsDisplayInRectIMP) {
-        Method setNeedsDisplayInRectMethod = class_getInstanceMethod([NSView class], @selector(setNeedsDisplayInRect:));
-        ASSERT(setNeedsDisplayInRectMethod);
-        oldSetNeedsDisplayInRectIMP = method_setImplementation(setNeedsDisplayInRectMethod, (IMP)setNeedsDisplayInRect);
-        ASSERT(oldSetNeedsDisplayInRectIMP);
-    }
-
+    method_exchangeImplementations(class_getInstanceMethod([NSView class], @selector(setNeedsDisplayInRect:)), class_getInstanceMethod([NSView class], @selector(_web_setNeedsDisplayInRect:)));
 #endif
-
 }
 
 - (void)dealloc
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to