Skip to content

Commit

Permalink
Bug 1698235 - Add some error handling when using RemotePrintJobChild …
Browse files Browse the repository at this point in the history
…which may be destroyed. r=TYLin

Differential Revision: https://phabricator.services.mozilla.com/D108711
  • Loading branch information
Mats Palmgren committed Mar 18, 2021
1 parent ea66000 commit 6adb31f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 5 deletions.
2 changes: 1 addition & 1 deletion layout/generic/nsPageSequenceFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ nsresult nsPageSequenceFrame::DoPageEnd() {
if (PresContext()->IsRootPaginatedDocument()) {
PR_PL(("***************** End Page (DoPageEnd) *****************\n"));
rv = PresContext()->DeviceContext()->EndPage();
NS_ENSURE_SUCCESS(rv, rv);
// Fall through to clean up resources/state below even if EndPage failed.
}

ResetPrintCanvasList();
Expand Down
4 changes: 4 additions & 0 deletions layout/printing/ipc/RemotePrintJobChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mozilla::ipc::IPCResult RemotePrintJobChild::RecvPrintInitializationResult(
}

PRFileDesc* RemotePrintJobChild::GetNextPageFD() {
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mNextPageFD);
PRFileDesc* fd = mNextPageFD;
mNextPageFD = nullptr;
Expand All @@ -51,6 +52,7 @@ PRFileDesc* RemotePrintJobChild::GetNextPageFD() {

void RemotePrintJobChild::SetNextPageFD(
const mozilla::ipc::FileDescriptor& aFd) {
MOZ_ASSERT(!mDestroyed);
auto handle = aFd.ClonePlatformHandle();
mNextPageFD = PR_ImportFile(PROsfd(handle.release()));
}
Expand Down Expand Up @@ -82,12 +84,14 @@ mozilla::ipc::IPCResult RemotePrintJobChild::RecvAbortPrint(
}

void RemotePrintJobChild::SetPagePrintTimer(nsPagePrintTimer* aPagePrintTimer) {
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(aPagePrintTimer);

mPagePrintTimer = aPagePrintTimer;
}

void RemotePrintJobChild::SetPrintJob(nsPrintJob* aPrintJob) {
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(aPrintJob);

mPrintJob = aPrintJob;
Expand Down
2 changes: 2 additions & 0 deletions layout/printing/ipc/RemotePrintJobChild.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class RemotePrintJobChild final : public PRemotePrintJobChild,

PRFileDesc* GetNextPageFD();

[[nodiscard]] bool IsDestroyed() const { return mDestroyed; }

private:
~RemotePrintJobChild() final;
void SetNextPageFD(const mozilla::ipc::FileDescriptor& aFd);
Expand Down
31 changes: 27 additions & 4 deletions widget/nsDeviceContextSpecProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ NS_IMETHODIMP
nsDeviceContextSpecProxy::BeginDocument(const nsAString& aTitle,
const nsAString& aPrintToFileName,
int32_t aStartPage, int32_t aEndPage) {
if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
mRemotePrintJob = nullptr;
return NS_ERROR_NOT_AVAILABLE;
}

mRecorder = new mozilla::layout::DrawEventRecorderPRFileDesc();
nsresult rv = mRemotePrintJob->InitializePrint(
nsString(aTitle), nsString(aPrintToFileName), aStartPage, aEndPage);
Expand All @@ -151,29 +156,47 @@ nsDeviceContextSpecProxy::BeginDocument(const nsAString& aTitle,

NS_IMETHODIMP
nsDeviceContextSpecProxy::EndDocument() {
if (mRemotePrintJob) {
Unused << mRemotePrintJob->SendFinalizePrint();
if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
mRemotePrintJob = nullptr;
return NS_ERROR_NOT_AVAILABLE;
}

Unused << mRemotePrintJob->SendFinalizePrint();

return NS_OK;
}

NS_IMETHODIMP
nsDeviceContextSpecProxy::AbortDocument() {
if (mRemotePrintJob) {
Unused << mRemotePrintJob->SendAbortPrint(NS_OK);
if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
mRemotePrintJob = nullptr;
return NS_ERROR_NOT_AVAILABLE;
}

Unused << mRemotePrintJob->SendAbortPrint(NS_OK);

return NS_OK;
}

NS_IMETHODIMP
nsDeviceContextSpecProxy::BeginPage() {
if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
mRemotePrintJob = nullptr;
return NS_ERROR_NOT_AVAILABLE;
}

mRecorder->OpenFD(mRemotePrintJob->GetNextPageFD());

return NS_OK;
}

NS_IMETHODIMP
nsDeviceContextSpecProxy::EndPage() {
if (!mRemotePrintJob || mRemotePrintJob->IsDestroyed()) {
mRemotePrintJob = nullptr;
return NS_ERROR_NOT_AVAILABLE;
}

// Send the page recording to the parent.
mRecorder->Close();
mRemotePrintJob->ProcessPage(std::move(mRecorder->TakeDependentSurfaces()));
Expand Down

0 comments on commit 6adb31f

Please sign in to comment.