Changeset 196267 in webkit


Ignore:
Timestamp:
Feb 8, 2016 12:53:21 PM (8 years ago)
Author:
andersca@apple.com
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.

Location:
trunk/Source/WebKit/mac
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/mac/ChangeLog

    r196239 r196267  
     12016-02-08  Anders Carlsson  <andersca@apple.com>
     2
     3        Crash when trying to chain to the old -[NSView setNeedsDisplayInRect:]
     4        https://bugs.webkit.org/show_bug.cgi?id=154001
     5        rdar://problem/24519975
     6
     7        Reviewed by Dan Bernstein.
     8
     9        If our replaced -[NSView setNeedsDisplayInRect:] is called before the old IMP has been initialized,
     10        we can end up trying to call a null pointer.
     11       
     12        Fix this by using method_exchangeImplementations instead of method_setImplementation, since the former is done
     13        atomically.
     14
     15        * WebView/WebHTMLView.mm:
     16        (-[NSView _web_setNeedsDisplayInRect:]):
     17        (+[WebHTMLViewPrivate initialize]):
     18        (setNeedsDisplayInRect): Deleted.
     19
    1202016-02-07  Dan Bernstein  <mitz@apple.com>
    221
  • trunk/Source/WebKit/mac/WebView/WebHTMLView.mm

    r196070 r196267  
    689689
    690690#if !PLATFORM(IOS)
    691 static IMP oldSetNeedsDisplayInRectIMP;
    692 
    693 static void setNeedsDisplayInRect(NSView *self, SEL cmd, NSRect invalidRect)
    694 {
     691
     692@interface NSView (WebSetNeedsDisplayInRect)
     693- (void)_web_setNeedsDisplayInRect:(NSRect)invalidRect;
     694@end
     695
     696@implementation NSView (WebSetNeedsDisplayInRect)
     697
     698- (void)_web_setNeedsDisplayInRect:(NSRect)invalidRect
     699{
     700    // Note that we call method_exchangeImplementations below, so any calls
     701    // to _web_setNeedsDisplayInRect: will actually call -[NSView setNeedsDisplayInRect:].
     702
    695703    if (![NSThread isMainThread] || ![self _drawnByAncestor]) {
    696         wtfCallIMP<id>(oldSetNeedsDisplayInRectIMP, self, cmd, invalidRect);
     704        [self _web_setNeedsDisplayInRect:invalidRect];
    697705        return;
    698706    }
     
    704712
    705713    if (!enclosingWebFrameView) {
    706         wtfCallIMP<id>(oldSetNeedsDisplayInRectIMP, self, cmd, invalidRect);
     714        [self _web_setNeedsDisplayInRect:invalidRect];
    707715        return;
    708716    }
     
    711719    FrameView* frameView = coreFrame ? coreFrame->view() : 0;
    712720    if (!frameView || !frameView->isEnclosedInCompositingLayer()) {
    713         wtfCallIMP<id>(oldSetNeedsDisplayInRectIMP, self, cmd, invalidRect);
     721        [self _web_setNeedsDisplayInRect:invalidRect];
    714722        return;
    715723    }
     
    722730    frameView->invalidateRect(invalidRectInFrameViewCoordinates);
    723731}
     732
     733@end
    724734
    725735@interface NSApplication (WebNSApplicationDetails)
     
    10271037    }
    10281038
    1029     if (!oldSetNeedsDisplayInRectIMP) {
    1030         Method setNeedsDisplayInRectMethod = class_getInstanceMethod([NSView class], @selector(setNeedsDisplayInRect:));
    1031         ASSERT(setNeedsDisplayInRectMethod);
    1032         oldSetNeedsDisplayInRectIMP = method_setImplementation(setNeedsDisplayInRectMethod, (IMP)setNeedsDisplayInRect);
    1033         ASSERT(oldSetNeedsDisplayInRectIMP);
    1034     }
    1035 
    1036 #endif
    1037 
     1039    method_exchangeImplementations(class_getInstanceMethod([NSView class], @selector(setNeedsDisplayInRect:)), class_getInstanceMethod([NSView class], @selector(_web_setNeedsDisplayInRect:)));
     1040#endif
    10381041}
    10391042
Note: See TracChangeset for help on using the changeset viewer.