Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1987)

Unified Diff: core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp

Issue 1153633009: Fix potentially massive memory leak in CPDF_DIBSource::LoadJpxBitmap(). (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: nits Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
index 3fabdf9f4ff878b035d41f5d0eb9a59a9fb4de02..dc985956cb56041b209fd4ad2e57dc61c743a933 100644
--- a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
+++ b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
@@ -4,6 +4,7 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+#include "../../../../third_party/base/nonstd_unique_ptr.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "../../../include/fpdfapi/fpdf_pageobj.h"
#include "../../../include/fpdfapi/fpdf_render.h"
@@ -55,6 +56,49 @@ FX_SAFE_DWORD CalculatePitch32(int bpp, int width)
return pitch;
}
+// Wrapper class to hold objects allocated in CPDF_DIBSource::LoadJpxBitmap(),
+// because nonstd::unique_ptr does not support custom deleters yet.
+class JpxBitMapContext
+{
+ public:
+ explicit JpxBitMapContext(ICodec_JpxModule* jpx_module)
+ : jpx_module_(jpx_module),
+ ctx_(nullptr),
+ output_offsets_(nullptr) {}
+
+ ~JpxBitMapContext() {
+ FX_Free(output_offsets_);
+ jpx_module_->DestroyDecoder(ctx_);
+ }
+
+ // Takes ownership of |ctx|.
+ void set_context(void* ctx) {
+ ctx_ = ctx;
+ }
+
+ void* context() {
+ return ctx_;
+ }
+
+ // Takes ownership of |output_offsets|.
+ void set_output_offsets(FX_LPBYTE output_offsets) {
Tom Sepez 2015/06/06 19:05:04 nit: prefer void* to LPBYTE in new code.
Lei Zhang 2015/06/08 19:35:20 LPBYTE is unsigned char*.
+ output_offsets_ = output_offsets;
+ }
+
+ FX_LPBYTE output_offsets() {
+ return output_offsets_;
+ }
+
+ private:
+ ICodec_JpxModule* jpx_module_; // Weak pointer.
+ void* ctx_; // Decoder context, owned.
+ FX_LPBYTE output_offsets_; // Output offets for decoding, owned.
+
+ // Disallow evil constructors
+ JpxBitMapContext(const JpxBitMapContext&);
+ void operator=(const JpxBitMapContext&);
+};
+
} // namespace
CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatteColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const
@@ -629,30 +673,37 @@ int CPDF_DIBSource::CreateDecoder()
void CPDF_DIBSource::LoadJpxBitmap()
{
ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule();
- if (pJpxModule == NULL) {
+ if (!pJpxModule)
return;
- }
- FX_LPVOID ctx = pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), m_pStreamAcc->GetSize(), m_pColorSpace != NULL);
- if (ctx == NULL) {
+
+ nonstd::unique_ptr<JpxBitMapContext> context(
+ new JpxBitMapContext(pJpxModule));
+ context->set_context(pJpxModule->CreateDecoder(m_pStreamAcc->GetData(),
+ m_pStreamAcc->GetSize(),
+ m_pColorSpace != nullptr));
+ if (!context->context())
return;
- }
- FX_DWORD width = 0, height = 0, codestream_nComps = 0, image_nComps = 0;
- pJpxModule->GetImageInfo(ctx, width, height, codestream_nComps, image_nComps);
- if ((int)width < m_Width || (int)height < m_Height) {
- pJpxModule->DestroyDecoder(ctx);
+
+ FX_DWORD width = 0;
+ FX_DWORD height = 0;
+ FX_DWORD codestream_nComps = 0;
+ FX_DWORD image_nComps = 0;
+ pJpxModule->GetImageInfo(context->context(), width, height,
+ codestream_nComps, image_nComps);
+ if ((int)width < m_Width || (int)height < m_Height)
return;
- }
+
int output_nComps;
- FX_BOOL bTranslateColor, bSwapRGB = FALSE;
+ FX_BOOL bTranslateColor;
+ FX_BOOL bSwapRGB = FALSE;
if (m_pColorSpace) {
- if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) {
+ if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents())
return;
- }
output_nComps = codestream_nComps;
bTranslateColor = FALSE;
if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) {
bSwapRGB = TRUE;
- m_pColorSpace = NULL;
+ m_pColorSpace = nullptr;
}
} else {
bTranslateColor = TRUE;
@@ -683,32 +734,35 @@ void CPDF_DIBSource::LoadJpxBitmap()
m_pCachedBitmap = new CFX_DIBitmap;
if (!m_pCachedBitmap->Create(width, height, format)) {
delete m_pCachedBitmap;
- m_pCachedBitmap = NULL;
+ m_pCachedBitmap = nullptr;
return;
}
m_pCachedBitmap->Clear(0xFFFFFFFF);
- FX_LPBYTE output_offsets = FX_Alloc(FX_BYTE, output_nComps);
- for (int i = 0; i < output_nComps; i ++) {
- output_offsets[i] = i;
- }
+ context->set_output_offsets(FX_Alloc(FX_BYTE, output_nComps));
+ for (int i = 0; i < output_nComps; ++i)
+ context->output_offsets()[i] = i;
if (bSwapRGB) {
- output_offsets[0] = 2;
- output_offsets[2] = 0;
- }
- if (!pJpxModule->Decode(ctx, m_pCachedBitmap->GetBuffer(), m_pCachedBitmap->GetPitch(), bTranslateColor, output_offsets)) {
+ context->output_offsets()[0] = 2;
+ context->output_offsets()[2] = 0;
+ }
+ if (!pJpxModule->Decode(context->context(),
+ m_pCachedBitmap->GetBuffer(),
+ m_pCachedBitmap->GetPitch(),
+ bTranslateColor,
+ context->output_offsets())) {
delete m_pCachedBitmap;
Tom Sepez 2015/06/06 19:05:04 nit: can m_pCachedBitmap be a unique_ptr?
Lei Zhang 2015/06/08 19:35:20 Done.
- m_pCachedBitmap = NULL;
+ m_pCachedBitmap = nullptr;
return;
Tom Sepez 2015/06/06 19:05:04 Nit: presumably this is the return that leaks, rig
Lei Zhang 2015/06/08 19:35:20 The failures are on line 700 above. "if (codestrea
}
- FX_Free(output_offsets);
- pJpxModule->DestroyDecoder(ctx);
- if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED && m_bpc < 8) {
+ if (m_pColorSpace &&
+ m_pColorSpace->GetFamily() == PDFCS_INDEXED &&
+ m_bpc < 8) {
int scale = 8 - m_bpc;
- for (FX_DWORD row = 0; row < height; row ++) {
+ for (FX_DWORD row = 0; row < height; ++row) {
FX_LPBYTE scanline = (FX_LPBYTE)m_pCachedBitmap->GetScanline(row);
- for (FX_DWORD col = 0; col < width; col ++) {
+ for (FX_DWORD col = 0; col < width; ++col) {
*scanline = (*scanline) >> scale;
- scanline++;
+ ++scanline;
}
}
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698