Title: [271384] trunk/Source/WebKit
Revision
271384
Author
[email protected]
Date
2021-01-11 15:54:27 -0800 (Mon, 11 Jan 2021)

Log Message

Crash in pageDidComputePageRects()
https://bugs.webkit.org/show_bug.cgi?id=220518
<rdar://problem/71065870>

Reviewed by Ryosuke Niwa.

Make _printOperation a weak pointer and check it before use.
Since WKPrintingView is ref counted, a reference could still exist
even if _printOperation is nil. Remove the comment as it is not a
justification for a raw pointer.

* UIProcess/mac/WKPrintingView.h:
* UIProcess/mac/WKPrintingView.mm:
(-[WKPrintingView _adjustPrintingMarginsForHeaderAndFooter]):
(-[WKPrintingView _firstPrintedPageNumber]):
(-[WKPrintingView _lastPrintedPageNumber]):
(-[WKPrintingView _preparePDFDataForPrintingOnSecondaryThread]):
(pageDidComputePageRects):
(-[WKPrintingView _askPageToComputePageRects]):
(-[WKPrintingView knowsPageRange:]):
(-[WKPrintingView _drawPreview:]):
(-[WKPrintingView drawRect:]):
(-[WKPrintingView _drawPageBorderWithSizeOnMainThread:]):
(-[WKPrintingView drawPageBorderWithSize:]):
(-[WKPrintingView rectForPage:]):
(-[WKPrintingView locationOfPrintRect:]):
(-[WKPrintingView beginDocument]):
(-[WKPrintingView endDocument]):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (271383 => 271384)


--- trunk/Source/WebKit/ChangeLog	2021-01-11 23:30:27 UTC (rev 271383)
+++ trunk/Source/WebKit/ChangeLog	2021-01-11 23:54:27 UTC (rev 271384)
@@ -1,3 +1,34 @@
+2021-01-11  Kate Cheney  <[email protected]>
+
+        Crash in pageDidComputePageRects()
+        https://bugs.webkit.org/show_bug.cgi?id=220518
+        <rdar://problem/71065870>
+
+        Reviewed by Ryosuke Niwa.
+
+        Make _printOperation a weak pointer and check it before use.
+        Since WKPrintingView is ref counted, a reference could still exist
+        even if _printOperation is nil. Remove the comment as it is not a
+        justification for a raw pointer.
+
+        * UIProcess/mac/WKPrintingView.h:
+        * UIProcess/mac/WKPrintingView.mm:
+        (-[WKPrintingView _adjustPrintingMarginsForHeaderAndFooter]):
+        (-[WKPrintingView _firstPrintedPageNumber]):
+        (-[WKPrintingView _lastPrintedPageNumber]):
+        (-[WKPrintingView _preparePDFDataForPrintingOnSecondaryThread]):
+        (pageDidComputePageRects):
+        (-[WKPrintingView _askPageToComputePageRects]):
+        (-[WKPrintingView knowsPageRange:]):
+        (-[WKPrintingView _drawPreview:]):
+        (-[WKPrintingView drawRect:]):
+        (-[WKPrintingView _drawPageBorderWithSizeOnMainThread:]):
+        (-[WKPrintingView drawPageBorderWithSize:]):
+        (-[WKPrintingView rectForPage:]):
+        (-[WKPrintingView locationOfPrintRect:]):
+        (-[WKPrintingView beginDocument]):
+        (-[WKPrintingView endDocument]):
+
 2021-01-11  Sihui Liu  <[email protected]>
 
         Make SpeechRecognition permission error more informative

Modified: trunk/Source/WebKit/UIProcess/mac/WKPrintingView.h (271383 => 271384)


--- trunk/Source/WebKit/UIProcess/mac/WKPrintingView.h	2021-01-11 23:30:27 UTC (rev 271383)
+++ trunk/Source/WebKit/UIProcess/mac/WKPrintingView.h	2021-01-11 23:54:27 UTC (rev 271384)
@@ -44,7 +44,7 @@
 
 @interface WKPrintingView : NSView {
 @public
-    NSPrintOperation *_printOperation; // WKPrintingView is owned by the operation.
+    WeakObjCPtr<NSPrintOperation> _printOperation;
     RetainPtr<NSView> _wkView;
 
     RefPtr<WebKit::WebFrameProxy> _webFrame;

Modified: trunk/Source/WebKit/UIProcess/mac/WKPrintingView.mm (271383 => 271384)


--- trunk/Source/WebKit/UIProcess/mac/WKPrintingView.mm	2021-01-11 23:30:27 UTC (rev 271383)
+++ trunk/Source/WebKit/UIProcess/mac/WKPrintingView.mm	2021-01-11 23:54:27 UTC (rev 271384)
@@ -131,7 +131,10 @@
 {
     ASSERT(RunLoop::isMain()); // This function calls the client, which should only be done on main thread.
 
-    NSPrintInfo *info = [_printOperation printInfo];
+    if (!_printOperation)
+        return;
+
+    NSPrintInfo *info = [_printOperation.get() printInfo];
     NSMutableDictionary *infoDictionary = [info dictionary];
 
     // We need to modify the top and bottom margins in the NSPrintInfo to account for the space needed by the
@@ -183,8 +186,11 @@
 
 - (NSUInteger)_firstPrintedPageNumber
 {
+    if (!_printOperation)
+        return 0;
+
     // Need to directly access the dictionary because -[NSPrintOperation pageRange] verifies pagination, potentially causing recursion.
-    return [[[[_printOperation printInfo] dictionary] objectForKey:NSPrintFirstPage] unsignedIntegerValue];
+    return [[[[_printOperation.get() printInfo] dictionary] objectForKey:NSPrintFirstPage] unsignedIntegerValue];
 }
 
 - (NSUInteger)_lastPrintedPageNumber
@@ -191,9 +197,12 @@
 {
     ASSERT([self _hasPageRects]);
 
+    if (!_printOperation)
+        return 0;
+
     // Need to directly access the dictionary because -[NSPrintOperation pageRange] verifies pagination, potentially causing recursion.
-    NSUInteger firstPage = [[[[_printOperation printInfo] dictionary] objectForKey:NSPrintFirstPage] unsignedIntegerValue];
-    NSUInteger lastPage = [[[[_printOperation printInfo] dictionary] objectForKey:NSPrintLastPage] unsignedIntegerValue];
+    NSUInteger firstPage = [[[[_printOperation.get() printInfo] dictionary] objectForKey:NSPrintFirstPage] unsignedIntegerValue];
+    NSUInteger lastPage = [[[[_printOperation.get() printInfo] dictionary] objectForKey:NSPrintLastPage] unsignedIntegerValue];
     if (lastPage - firstPage >= _printingPageRects.size())
         return _printingPageRects.size();
     return lastPage;
@@ -245,7 +254,7 @@
 {
     ASSERT(RunLoop::isMain());
 
-    if (!_webFrame->page()) {
+    if (!_webFrame->page() || !_printOperation) {
         _printingCallbackCondition.notifyOne();
         return;
     }
@@ -264,7 +273,7 @@
     ASSERT(firstPage <= lastPage);
     LOG(Printing, "WKPrintingView requesting PDF data for pages %u...%u", firstPage, lastPage);
 
-    WebKit::PrintInfo printInfo([_printOperation printInfo]);
+    WebKit::PrintInfo printInfo([_printOperation.get() printInfo]);
     // Return to printing mode if we're already back to screen (e.g. due to window resizing).
     _webFrame->page()->beginPrinting(_webFrame.get(), printInfo);
 
@@ -298,6 +307,8 @@
     ASSERT(RunLoop::isMain());
 
     WKPrintingView *view = context->view.get();
+    if (!view->_printOperation)
+        return;
 
     // If the user has already changed print setup, then this response is obsolete.
     if (context->callbackID == view->_expectedComputedPagesCallback) {
@@ -324,7 +335,7 @@
         LOG(Printing, "WKPrintingView setting frame size to x:%g y:%g width:%g height:%g", newFrameSize.origin.x, newFrameSize.origin.y, newFrameSize.size.width, newFrameSize.size.height);
         [view setFrame:newFrameSize];
         // Set @page margin.
-        auto *printInfo = [view->_printOperation printInfo];
+        auto *printInfo = [view->_printOperation.get() printInfo];
         [printInfo setTopMargin:computedPageMargin.top()];
         [printInfo setBottomMargin:computedPageMargin.bottom()];
         [printInfo setLeftMargin:computedPageMargin.left()];
@@ -344,7 +355,7 @@
 {
     ASSERT(RunLoop::isMain());
 
-    if (!_webFrame->page())
+    if (!_webFrame->page() || !_printOperation)
         return NO;
 
     ASSERT(!_expectedComputedPagesCallback);
@@ -358,7 +369,7 @@
     context->view = self;
     context->callbackID = _expectedComputedPagesCallback;
 
-    _webFrame->page()->computePagesForPrinting(_webFrame.get(), WebKit::PrintInfo([_printOperation printInfo]), WTFMove(callback));
+    _webFrame->page()->computePagesForPrinting(_webFrame.get(), WebKit::PrintInfo([_printOperation.get() printInfo]), WTFMove(callback));
     return YES;
 }
 
@@ -384,8 +395,12 @@
 - (BOOL)knowsPageRange:(NSRangePointer)range
 {
     LOG(Printing, "-[WKPrintingView %p knowsPageRange:], %s, %s", self, [self _hasPageRects] ? "print data is available" : "print data is not available yet", RunLoop::isMain() ? "on main thread" : "on secondary thread");
-    ASSERT(_printOperation == [NSPrintOperation currentOperation]);
+    
+    if (!_printOperation)
+        return NO;
 
+    ASSERT(_printOperation.get() == [NSPrintOperation currentOperation]);
+
     // Assuming that once we switch to printing from a secondary thread, we don't go back.
     ASSERT(!_isPrintingFromSecondaryThread || !RunLoop::isMain());
     if (!RunLoop::isMain())
@@ -518,9 +533,12 @@
                 // There is no need to ask again.
                 _latestExpectedPreviewCallback = existingCallback;
             } else {
+                if (!_printOperation)
+                    return;
+
                 // Preview isn't available yet, request it asynchronously.
                 // Return to printing mode if we're already back to screen (e.g. due to window resizing).
-                _webFrame->page()->beginPrinting(_webFrame.get(), WebKit::PrintInfo([_printOperation printInfo]));
+                _webFrame->page()->beginPrinting(_webFrame.get(), WebKit::PrintInfo([_printOperation.get() printInfo]));
 
                 IPCCallbackContext* context = new IPCCallbackContext;
                 auto callback = WebKit::ImageCallback::create([context](const WebKit::ShareableBitmap::Handle& imageHandle, WebKit::CallbackBase::Error) {
@@ -533,7 +551,7 @@
                 context->view = self;
                 context->callbackID = callback->callbackID().toInteger();
 
-                _webFrame->page()->drawRectToImage(_webFrame.get(), WebKit::PrintInfo([_printOperation printInfo]), scaledPrintingRect, imageSize, WTFMove(callback));
+                _webFrame->page()->drawRectToImage(_webFrame.get(), WebKit::PrintInfo([_printOperation.get() printInfo]), scaledPrintingRect, imageSize, WTFMove(callback));
                 return;
             }
         }
@@ -554,8 +572,11 @@
 {
     LOG(Printing, "WKPrintingView %p printing rect x:%g, y:%g, width:%g, height:%g%s", self, nsRect.origin.x, nsRect.origin.y, nsRect.size.width, nsRect.size.height, [self _isPrintingPreview] ? " for preview" : "");
 
-    ASSERT(_printOperation == [NSPrintOperation currentOperation]);
+    if (!_printOperation)
+        return;
 
+    ASSERT(_printOperation.get() == [NSPrintOperation currentOperation]);
+
     // Always use the light appearance when printing.
     WebCore::LocalDefaultSystemAppearance localAppearance(false);
 
@@ -604,12 +625,15 @@
 {
     ASSERT(RunLoop::isMain());
 
+    if (!_printOperation)
+        return;
+
     // When printing from a secondary thread, the main thread doesn't have graphics context and printing operation set up.
     NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
-    [NSGraphicsContext setCurrentContext:[_printOperation context]];
+    [NSGraphicsContext setCurrentContext:[_printOperation.get() context]];
 
     ASSERT(![NSPrintOperation currentOperation]);
-    [NSPrintOperation setCurrentOperation:_printOperation];
+    [NSPrintOperation setCurrentOperation:_printOperation.get().get()];
 
     [self drawPageBorderWithSize:borderSize];
 
@@ -619,9 +643,12 @@
 
 - (void)drawPageBorderWithSize:(NSSize)borderSize
 {
-    ASSERT(NSEqualSizes(borderSize, [[_printOperation printInfo] paperSize]));    
-    ASSERT(_printOperation == [NSPrintOperation currentOperation]);
+    if (!_printOperation)
+        return;
 
+    ASSERT(NSEqualSizes(borderSize, [[_printOperation.get() printInfo] paperSize]));
+    ASSERT(_printOperation.get() == [NSPrintOperation currentOperation]);
+
     if (!RunLoop::isMain()) {
         // Don't call the client from a secondary thread.
         NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[WKPrintingView instanceMethodSignatureForSelector:@selector(_drawPageBorderWithSizeOnMainThread:)]];
@@ -636,7 +663,7 @@
 
     // The header and footer rect height scales with the page, but the width is always
     // all the way across the printed page (inset by printing margins).
-    NSPrintInfo *printInfo = [_printOperation printInfo];
+    NSPrintInfo *printInfo = [_printOperation.get() printInfo];
     CGFloat scale = [printInfo scalingFactor];
     NSSize paperSize = [printInfo paperSize];
     CGFloat headerFooterLeft = [printInfo leftMargin] / scale;
@@ -658,7 +685,10 @@
 
 - (NSRect)rectForPage:(NSInteger)page
 {
-    ASSERT(_printOperation == [NSPrintOperation currentOperation]);
+    if (!_printOperation)
+        return NSZeroRect;
+
+    ASSERT(_printOperation.get() == [NSPrintOperation currentOperation]);
     if (![self _hasPageRects]) {
         LOG(Printing, "-[WKPrintingView %p rectForPage:%d] - data is not yet available", self, (int)page);
         if (!_webFrame->page()) {
@@ -686,14 +716,20 @@
 // Temporary workaround for <rdar://problem/8944535>. Force correct printout positioning.
 - (NSPoint)locationOfPrintRect:(NSRect)aRect
 {
-    ASSERT(_printOperation == [NSPrintOperation currentOperation]);
-    return NSMakePoint([[_printOperation printInfo] leftMargin], [[_printOperation printInfo] bottomMargin]);
+    if (!_printOperation)
+        return NSZeroPoint;
+
+    ASSERT(_printOperation.get() == [NSPrintOperation currentOperation]);
+    return NSMakePoint([[_printOperation.get() printInfo] leftMargin], [[_printOperation.get() printInfo] bottomMargin]);
 }
 
 - (void)beginDocument
 {
-    ASSERT(_printOperation == [NSPrintOperation currentOperation]);
+    if (!_printOperation)
+        return;
 
+    ASSERT(_printOperation.get() == [NSPrintOperation currentOperation]);
+
     // Forcing preview update gets us here, but page setup hasn't actually changed.
     if (isForcingPreviewUpdate)
         return;
@@ -707,8 +743,11 @@
 
 - (void)endDocument
 {
-    ASSERT(_printOperation == [NSPrintOperation currentOperation]);
+    if (!_printOperation)
+        return;
 
+    ASSERT(_printOperation.get() == [NSPrintOperation currentOperation]);
+
     // Forcing preview update gets us here, but page setup hasn't actually changed.
     if (isForcingPreviewUpdate)
         return;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to