diff options
author | thestig <thestig@chromium.org> | 2016-08-09 15:46:20 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-09 15:46:20 -0700 |
commit | dc359b03ab6a70ee52a91119ff6704cae92f4809 (patch) | |
tree | 131cb9b1846f4be24c9cb7c54b30975c6a858071 /core | |
parent | 39ba18a64283ef3fc3c4aedf537a09835f90862e (diff) | |
download | pdfium-dc359b03ab6a70ee52a91119ff6704cae92f4809.tar.xz |
Fix a leak with FPDFPageObj_NewImgeObj().
BUG=pdfium:545
Review-Url: https://codereview.chromium.org/2194393002
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp | 4 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_page/cpdf_image.cpp | 95 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_page/cpdf_imageobject.cpp | 43 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_page/fpdf_page_doc.cpp | 6 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 10 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_page/include/cpdf_image.h | 20 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_page/include/cpdf_imageobject.h | 11 |
7 files changed, 101 insertions, 88 deletions
diff --git a/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp index a85591ceef..0e4bab1ae1 100644 --- a/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp @@ -99,12 +99,12 @@ void CPDF_PageContentGenerator::ProcessImage(CFX_ByteTextBuf& buf, uint32_t dwSavedObjNum = pStream->GetObjNum(); CFX_ByteString name = RealizeResource(pStream, "XObject"); if (dwSavedObjNum == 0) { - pImage->Release(); - pImageObj->m_pImage = m_pDocument->GetPageData()->GetImage(pStream); + pImageObj->SetUnownedImage(m_pDocument->GetPageData()->GetImage(pStream)); } buf << "/" << PDF_NameEncode(name) << " Do Q\n"; } } + void CPDF_PageContentGenerator::ProcessForm(CFX_ByteTextBuf& buf, const uint8_t* data, uint32_t size, diff --git a/core/fpdfapi/fpdf_page/cpdf_image.cpp b/core/fpdfapi/fpdf_page/cpdf_image.cpp index 63e006fc06..af361eb9f6 100644 --- a/core/fpdfapi/fpdf_page/cpdf_image.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_image.cpp @@ -6,6 +6,10 @@ #include "core/fpdfapi/fpdf_page/include/cpdf_image.h" +#include <algorithm> +#include <memory> +#include <vector> + #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" #include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_boolean.h" @@ -19,14 +23,35 @@ #include "core/fxge/include/fx_dib.h" CPDF_Image::CPDF_Image(CPDF_Document* pDoc) + : CPDF_Image(pDoc, nullptr, false) {} + +CPDF_Image::CPDF_Image(CPDF_Document* pDoc, CPDF_Stream* pStream, bool bInline) : m_pDIBSource(nullptr), m_pMask(nullptr), m_MatteColor(0), - m_pStream(nullptr), - m_bInline(FALSE), + m_pStream(pStream), + m_bInline(bInline), m_pInlineDict(nullptr), + m_Height(0), + m_Width(0), + m_bIsMask(false), + m_bInterpolate(false), m_pDocument(pDoc), - m_pOC(nullptr) {} + m_pOC(nullptr) { + if (!pStream) + return; + + CPDF_Dictionary* pDict = pStream->GetDict(); + if (m_bInline) + m_pInlineDict = ToDictionary(pDict->Clone()); + + m_pOC = pDict->GetDictBy("OC"); + m_bIsMask = + !pDict->KeyExist("ColorSpace") || pDict->GetIntegerBy("ImageMask"); + m_bInterpolate = !!pDict->GetIntegerBy("Interpolate"); + m_Height = pDict->GetIntegerBy("Height"); + m_Width = pDict->GetIntegerBy("Width"); +} CPDF_Image::~CPDF_Image() { if (m_bInline) { @@ -37,43 +62,18 @@ CPDF_Image::~CPDF_Image() { } } -void CPDF_Image::Release() { - if (m_bInline || (m_pStream && m_pStream->GetObjNum() == 0)) - delete this; -} - CPDF_Image* CPDF_Image::Clone() { if (m_pStream->GetObjNum()) return m_pDocument->GetPageData()->GetImage(m_pStream); - CPDF_Image* pImage = new CPDF_Image(m_pDocument); - pImage->LoadImageF(ToStream(m_pStream->Clone()), m_bInline); + CPDF_Image* pImage = + new CPDF_Image(m_pDocument, ToStream(m_pStream->Clone()), m_bInline); if (m_bInline) pImage->SetInlineDict(ToDictionary(m_pInlineDict->Clone(TRUE))); return pImage; } -FX_BOOL CPDF_Image::LoadImageF(CPDF_Stream* pStream, FX_BOOL bInline) { - m_pStream = pStream; - if (m_bInline && m_pInlineDict) { - m_pInlineDict->Release(); - m_pInlineDict = nullptr; - } - m_bInline = bInline; - CPDF_Dictionary* pDict = pStream->GetDict(); - if (m_bInline) { - m_pInlineDict = ToDictionary(pDict->Clone()); - } - m_pOC = pDict->GetDictBy("OC"); - m_bIsMask = - !pDict->KeyExist("ColorSpace") || pDict->GetIntegerBy("ImageMask"); - m_bInterpolate = pDict->GetIntegerBy("Interpolate"); - m_Height = pDict->GetIntegerBy("Height"); - m_Width = pDict->GetIntegerBy("Width"); - return TRUE; -} - CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { int32_t width; int32_t height; @@ -120,36 +120,23 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { return pDict; } -void CPDF_Image::SetJpegImage(uint8_t* pData, uint32_t size) { - CPDF_Dictionary* pDict = InitJPEG(pData, size); - if (!pDict) { - return; - } - m_pStream->InitStream(pData, size, pDict); -} - void CPDF_Image::SetJpegImage(IFX_FileRead* pFile) { uint32_t size = (uint32_t)pFile->GetSize(); - if (!size) { + if (!size) return; - } - uint32_t dwEstimateSize = size; - if (dwEstimateSize > 8192) { - dwEstimateSize = 8192; - } - uint8_t* pData = FX_Alloc(uint8_t, dwEstimateSize); - pFile->ReadBlock(pData, 0, dwEstimateSize); - CPDF_Dictionary* pDict = InitJPEG(pData, dwEstimateSize); - FX_Free(pData); + + uint32_t dwEstimateSize = std::min(size, 8192U); + std::vector<uint8_t> data(dwEstimateSize); + pFile->ReadBlock(data.data(), 0, dwEstimateSize); + CPDF_Dictionary* pDict = InitJPEG(data.data(), dwEstimateSize); if (!pDict && size > dwEstimateSize) { - pData = FX_Alloc(uint8_t, size); - pFile->ReadBlock(pData, 0, size); - pDict = InitJPEG(pData, size); - FX_Free(pData); + data.resize(size); + pFile->ReadBlock(data.data(), 0, size); + pDict = InitJPEG(data.data(), size); } - if (!pDict) { + if (!pDict) return; - } + m_pStream->InitStreamFromFile(pFile, pDict); } diff --git a/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp b/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp index e2defa8054..1fa14805aa 100644 --- a/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp @@ -6,22 +6,17 @@ #include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h" +#include <memory> + #include "core/fpdfapi/fpdf_page/include/cpdf_image.h" #include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" -CPDF_ImageObject::CPDF_ImageObject() : m_pImage(nullptr) {} +CPDF_ImageObject::CPDF_ImageObject() + : m_pImage(nullptr), m_pImageOwned(false) {} CPDF_ImageObject::~CPDF_ImageObject() { - if (!m_pImage) { - return; - } - if (m_pImage->IsInline() || - (m_pImage->GetStream() && m_pImage->GetStream()->GetObjNum() == 0)) { - delete m_pImage; - } else { - m_pImage->GetDocument()->GetPageData()->ReleaseImage(m_pImage->GetStream()); - } + Release(); } CPDF_ImageObject* CPDF_ImageObject::Clone() const { @@ -59,3 +54,31 @@ void CPDF_ImageObject::CalcBoundingBox() { m_Right = m_Top = 1.0f; m_Matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); } + +void CPDF_ImageObject::SetOwnedImage(std::unique_ptr<CPDF_Image> pImage) { + Release(); + m_pImage = pImage.release(); + m_pImageOwned = true; +} + +void CPDF_ImageObject::SetUnownedImage(CPDF_Image* pImage) { + Release(); + m_pImage = pImage; + m_pImageOwned = false; +} + +void CPDF_ImageObject::Release() { + if (m_pImageOwned) { + delete m_pImage; + m_pImage = nullptr; + m_pImageOwned = false; + return; + } + + if (!m_pImage) + return; + + CPDF_DocPageData* pPageData = m_pImage->GetDocument()->GetPageData(); + pPageData->ReleaseImage(m_pImage->GetStream()); + m_pImage = nullptr; +} diff --git a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp index f8d7575318..fa242ffb85 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp @@ -406,10 +406,8 @@ CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream) { if (it != m_ImageMap.end()) return it->second->AddRef(); - CPDF_Image* pImage = new CPDF_Image(m_pPDFDoc); - pImage->LoadImageF(pImageStream->AsStream(), false); - - CPDF_CountedImage* pCountedImage = new CPDF_CountedImage(pImage); + CPDF_CountedImage* pCountedImage = new CPDF_CountedImage( + new CPDF_Image(m_pPDFDoc, pImageStream->AsStream(), false)); m_ImageMap[dwImageObjNum] = pCountedImage; return pCountedImage->AddRef(); } diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 483a6b1fd6..991e4b1e9f 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -785,13 +785,13 @@ CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream, std::unique_ptr<CPDF_ImageObject> pImageObj(new CPDF_ImageObject); if (pImage) { - pImageObj->m_pImage = - m_pDocument->GetPageData()->GetImage(pImage->GetStream()); + pImageObj->SetUnownedImage( + m_pDocument->GetPageData()->GetImage(pImage->GetStream())); } else if (pStream->GetObjNum()) { - pImageObj->m_pImage = m_pDocument->LoadImageF(pStream); + pImageObj->SetUnownedImage(m_pDocument->LoadImageF(pStream)); } else { - pImageObj->m_pImage = new CPDF_Image(m_pDocument); - pImageObj->m_pImage->LoadImageF(pStream, bInline); + pImageObj->SetOwnedImage( + WrapUnique(new CPDF_Image(m_pDocument, pStream, bInline))); } SetGraphicStates(pImageObj.get(), pImageObj->GetImage()->IsMask(), FALSE, FALSE); diff --git a/core/fpdfapi/fpdf_page/include/cpdf_image.h b/core/fpdfapi/fpdf_page/include/cpdf_image.h index f475e53478..ef48a04f95 100644 --- a/core/fpdfapi/fpdf_page/include/cpdf_image.h +++ b/core/fpdfapi/fpdf_page/include/cpdf_image.h @@ -28,12 +28,9 @@ class IFX_Pause; class CPDF_Image { public: explicit CPDF_Image(CPDF_Document* pDoc); + CPDF_Image(CPDF_Document* pDoc, CPDF_Stream* pStream, bool bInline); ~CPDF_Image(); - FX_BOOL LoadImageF(CPDF_Stream* pImageStream, FX_BOOL bInline); - - void Release(); - CPDF_Image* Clone(); CPDF_Dictionary* GetInlineDict() const { return m_pInlineDict; } @@ -47,9 +44,9 @@ class CPDF_Image { int32_t GetPixelHeight() const { return m_Height; } int32_t GetPixelWidth() const { return m_Width; } - FX_BOOL IsInline() { return m_bInline; } - FX_BOOL IsMask() const { return m_bIsMask; } - FX_BOOL IsInterpol() const { return m_bInterpolate; } + bool IsInline() const { return m_bInline; } + bool IsMask() const { return m_bIsMask; } + bool IsInterpol() const { return m_bInterpolate; } CFX_DIBSource* LoadDIBSource(CFX_DIBSource** ppMask = nullptr, uint32_t* pMatteColor = nullptr, @@ -59,7 +56,6 @@ class CPDF_Image { void SetInlineDict(CPDF_Dictionary* pDict) { m_pInlineDict = pDict; } void SetImage(const CFX_DIBitmap* pDIBitmap, int32_t iCompress); - void SetJpegImage(uint8_t* pImageData, uint32_t size); void SetJpegImage(IFX_FileRead* pFile); void ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pDIBitmap); @@ -81,13 +77,13 @@ class CPDF_Image { CPDF_Dictionary* InitJPEG(uint8_t* pData, uint32_t size); CPDF_Stream* m_pStream; - FX_BOOL m_bInline; + const bool m_bInline; CPDF_Dictionary* m_pInlineDict; int32_t m_Height; int32_t m_Width; - FX_BOOL m_bIsMask; - FX_BOOL m_bInterpolate; - CPDF_Document* m_pDocument; + bool m_bIsMask; + bool m_bInterpolate; + CPDF_Document* const m_pDocument; CPDF_Dictionary* m_pOC; }; diff --git a/core/fpdfapi/fpdf_page/include/cpdf_imageobject.h b/core/fpdfapi/fpdf_page/include/cpdf_imageobject.h index b2bffa707c..fdbd43c4a9 100644 --- a/core/fpdfapi/fpdf_page/include/cpdf_imageobject.h +++ b/core/fpdfapi/fpdf_page/include/cpdf_imageobject.h @@ -7,6 +7,8 @@ #ifndef CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_IMAGEOBJECT_H_ #define CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_IMAGEOBJECT_H_ +#include <memory> + #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" #include "core/fxcrt/include/fx_coordinates.h" @@ -27,9 +29,16 @@ class CPDF_ImageObject : public CPDF_PageObject { void CalcBoundingBox(); CPDF_Image* GetImage() const { return m_pImage; } + void SetOwnedImage(std::unique_ptr<CPDF_Image> pImage); + void SetUnownedImage(CPDF_Image* pImage); - CPDF_Image* m_pImage; CFX_Matrix m_Matrix; + + private: + void Release(); + + CPDF_Image* m_pImage; + bool m_pImageOwned; }; #endif // CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_IMAGEOBJECT_H_ |