Always check CFX_RenderDevice::CreateCompatibleBitmap() return value By checking the return value from CreateCompatibleBitmap(), there is no need to do a separate GetBuffer() check in CPDF_RenderStatus::GetBackdrop(). Fix some nits there as well. In CPDF_DeviceBuffer::OutputToDevice(), prevent a potential crash in case CreateCompatibleBitmap() fails. Bug: pdfium:2047 Change-Id: Ide7a6276de23339dec578bae2d1d8dfa3233770b Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/111993 Reviewed-by: Nigi <nigi@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_devicebuffer.cpp b/core/fpdfapi/render/cpdf_devicebuffer.cpp index 5bf308a..61611b2 100644 --- a/core/fpdfapi/render/cpdf_devicebuffer.cpp +++ b/core/fpdfapi/render/cpdf_devicebuffer.cpp
@@ -82,8 +82,10 @@ return; } auto pBuffer = pdfium::MakeRetain<CFX_DIBitmap>(); - m_pDevice->CreateCompatibleBitmap(pBuffer, m_pBitmap->GetWidth(), - m_pBitmap->GetHeight()); + if (!m_pDevice->CreateCompatibleBitmap(pBuffer, m_pBitmap->GetWidth(), + m_pBitmap->GetHeight())) { + return; + } m_pContext->GetBackground(m_pDevice, m_pObject, nullptr, m_Matrix); pBuffer->CompositeBitmap(0, 0, pBuffer->GetWidth(), pBuffer->GetHeight(), m_pBitmap, 0, 0, BlendMode::kNormal, nullptr, false);
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 39101f0..72aadce 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -701,21 +701,19 @@ int width = bbox.Width(); int height = bbox.Height(); auto pBackdrop = pdfium::MakeRetain<CFX_DIBitmap>(); - if (bBackAlphaRequired && !m_bDropObjects) - pBackdrop->Create(width, height, FXDIB_Format::kArgb); - else - m_pDevice->CreateCompatibleBitmap(pBackdrop, width, height); + if (bBackAlphaRequired && !m_bDropObjects) { + if (!pBackdrop->Create(width, height, FXDIB_Format::kArgb)) { + return nullptr; + } + } else { + if (!m_pDevice->CreateCompatibleBitmap(pBackdrop, width, height)) { + return nullptr; + } + } - if (pBackdrop->GetBuffer().empty()) - return nullptr; - - bool bNeedDraw; - if (pBackdrop->IsAlphaFormat()) - bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT); - else - bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS); - - if (!bNeedDraw) { + const int cap_to_check = + pBackdrop->IsAlphaFormat() ? FXRC_ALPHA_OUTPUT : FXRC_GET_BITS; + if (m_pDevice->GetRenderCaps() & cap_to_check) { m_pDevice->GetDIBits(pBackdrop, bbox.left, bbox.top); return pBackdrop; }
diff --git a/core/fxge/cfx_renderdevice.h b/core/fxge/cfx_renderdevice.h index b7ce809..8b45ef8 100644 --- a/core/fxge/cfx_renderdevice.h +++ b/core/fxge/cfx_renderdevice.h
@@ -64,9 +64,9 @@ int GetDeviceCaps(int id) const; RetainPtr<CFX_DIBitmap> GetBitmap() const; void SetBitmap(const RetainPtr<CFX_DIBitmap>& pBitmap); - bool CreateCompatibleBitmap(const RetainPtr<CFX_DIBitmap>& pDIB, - int width, - int height) const; + [[nodiscard]] bool CreateCompatibleBitmap(const RetainPtr<CFX_DIBitmap>& pDIB, + int width, + int height) const; const FX_RECT& GetClipBox() const { return m_ClipBox; } void SetBaseClip(const FX_RECT& rect); bool SetClip_PathFill(const CFX_Path& path,