Bug 1376693 - part1: Make nsPrintEngine::SetupToPrintContent() return early if mPrt->mPrintObject isn't initialized r?dholbert draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 19 Jul 2017 13:50:35 +0900
changeset 611017 3c90040c657babe02fd45c0b114400244b10e52e
parent 610973 1b065ffd8a535a0ad4c39a912af18e948e6a42c1
child 611018 3898c2d70c71aeb33eecc79d52cf7c7f7199ddf6
push id69097
push usermasayuki@d-toybox.com
push dateWed, 19 Jul 2017 05:32:07 +0000
reviewersdholbert
bugs1376693
milestone56.0a1
Bug 1376693 - part1: Make nsPrintEngine::SetupToPrintContent() return early if mPrt->mPrintObject isn't initialized r?dholbert nsPrintObject::mPresShell and nsPrintObject::mPresContext are initialized by nsPrintEngine::ReflowPrintObject(). However, while nsPrintEngine::DoCommonPrint() is initializing mPrt and mPrintObject, destroying nsAutoScriptBlocker may cause calling nsDocumentViewer::Destroy() or nsPrintEngine::FinishPrintPreview() directly. Then, nsPrintEngine::SetupToPrintContent() will be called. Therefore, nsPrintEngine::SetupToPrintContent() sometimes see uninitialized mPrt, or mPrt->mPrintObject->mPresShell and mPrt->mPrintObject->mPresContext. Therefore, this patch makes nsPrintEngine::SetupToPrintContent() check whether the necessary objects are already initialized. When one of them is not initialized as expected, it won't to do anything. Note that mPrt->mPrintObject is never nullptr with current design, but this patch makes the method check it for preventing similar crash which might be regressed with other bug fix in the future. MozReview-Commit-ID: JKfObRm5enm
layout/printing/nsPrintEngine.cpp
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -1678,17 +1678,26 @@ nsPrintEngine::ReconstructAndReflow(bool
   }
   return NS_OK;
 }
 
 //-------------------------------------------------------
 nsresult
 nsPrintEngine::SetupToPrintContent()
 {
-  if (NS_WARN_IF(!mPrt)) {
+  // This method may be called while DoCommonPrint() initializes the instance
+  // when its script blocker goes out of scope.  In such case, this cannot do
+  // its job as expected because some objects in mPrt have not been initialized
+  // yet but they are necessary.
+  // Note: it shouldn't be possible for mPrt->mPrintObject to be null; we
+  // just check it for good measure, as we check its owner & members.
+  if (NS_WARN_IF(!mPrt) ||
+      NS_WARN_IF(!mPrt->mPrintObject) ||
+      NS_WARN_IF(!mPrt->mPrintObject->mPresShell) ||
+      NS_WARN_IF(!mPrt->mPrintObject->mPresContext)) {
     return NS_ERROR_FAILURE;
   }
 
   bool didReconstruction = false;
 
   // This method works with mPrt->mPrintObject.  So, we need to guarantee that
   // it won't be deleted in this method.  We achieve this by holding a strong
   // local reference to mPrt, which in turn keeps mPrintObject alive.