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
--- 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.