From 3ba098595ae56b64eacc0c25ab76b89a4d78d920 Mon Sep 17 00:00:00 2001 From: tsepez Date: Fri, 14 Oct 2016 16:59:10 -0700 Subject: Update CPDF_IndirectObjectHolder APIs for unique objects. Doing so highlights a few places where ownership is dubious. Add convenience functions to return an unowned reference to a newly-created indirect object. Review-Url: https://codereview.chromium.org/2419173002 --- core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp | 22 +++++----- core/fpdfapi/edit/fpdf_edit_create.cpp | 8 ++-- core/fpdfapi/page/cpdf_docpagedata.cpp | 4 +- core/fpdfapi/page/cpdf_image.cpp | 14 +++--- core/fpdfapi/parser/cfdf_document.cpp | 6 +-- core/fpdfapi/parser/cpdf_array.cpp | 10 ++++- core/fpdfapi/parser/cpdf_array.h | 1 + core/fpdfapi/parser/cpdf_array_unittest.cpp | 7 +-- core/fpdfapi/parser/cpdf_data_avail.cpp | 5 ++- core/fpdfapi/parser/cpdf_dictionary.cpp | 10 ++++- core/fpdfapi/parser/cpdf_dictionary.h | 3 ++ core/fpdfapi/parser/cpdf_document.cpp | 50 +++++++++++---------- .../fpdfapi/parser/cpdf_indirect_object_holder.cpp | 51 +++++++++++++++++----- core/fpdfapi/parser/cpdf_indirect_object_holder.h | 28 +++++++++--- core/fpdfapi/parser/cpdf_object_unittest.cpp | 9 ++-- core/fpdfapi/parser/cpdf_parser.cpp | 7 +-- 16 files changed, 147 insertions(+), 88 deletions(-) (limited to 'core/fpdfapi') diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp index ad1ffaf687..654b69ec4a 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp @@ -52,10 +52,9 @@ void CPDF_PageContentGenerator::GenerateContent() { if (pContent) pPageDict->RemoveFor("Contents"); - CPDF_Stream* pStream = new CPDF_Stream; + CPDF_Stream* pStream = m_pDocument->AddIndirectStream(); pStream->SetData(buf.GetBuffer(), buf.GetLength()); - pPageDict->SetReferenceFor("Contents", m_pDocument, - m_pDocument->AddIndirectObject(pStream)); + pPageDict->SetReferenceFor("Contents", m_pDocument, pStream); } CFX_ByteString CPDF_PageContentGenerator::RealizeResource( @@ -63,10 +62,9 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource( const CFX_ByteString& bsType) { if (!m_pPage->m_pResources) { m_pPage->m_pResources = - new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - m_pPage->m_pFormDict->SetReferenceFor( - "Resources", m_pDocument, - m_pDocument->AddIndirectObject(m_pPage->m_pResources)); + m_pDocument->AddIndirectDictionary(m_pDocument->GetByteStringPool()); + m_pPage->m_pFormDict->SetReferenceFor("Resources", m_pDocument, + m_pPage->m_pResources); } CPDF_Dictionary* pResList = m_pPage->m_pResources->GetDictFor(bsType); if (!pResList) { @@ -82,8 +80,9 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource( } idnum++; } - pResList->SetReferenceFor(name, m_pDocument, - m_pDocument->AddIndirectObject(pResourceObj)); + // TODO(tsepez): check |pResourceObj| ownership. + pResList->SetReferenceFor(name, m_pDocument, m_pDocument->AddIndirectObject( + UniqueObject(pResourceObj))); return name; } @@ -170,8 +169,7 @@ void CPDF_PageContentGenerator::TransformContent(CFX_Matrix& matrix) { contentStream.LoadAllData(pStream); ProcessForm(buf, contentStream.GetData(), contentStream.GetSize(), matrix); } - CPDF_Stream* pStream = new CPDF_Stream; + CPDF_Stream* pStream = m_pDocument->AddIndirectStream(); pStream->SetData(buf.GetBuffer(), buf.GetLength()); - m_pPage->m_pFormDict->SetReferenceFor( - "Contents", m_pDocument, m_pDocument->AddIndirectObject(pStream)); + m_pPage->m_pFormDict->SetReferenceFor("Contents", m_pDocument, pStream); } diff --git a/core/fpdfapi/edit/fpdf_edit_create.cpp b/core/fpdfapi/edit/fpdf_edit_create.cpp index fae2b14449..5622b1dae7 100644 --- a/core/fpdfapi/edit/fpdf_edit_create.cpp +++ b/core/fpdfapi/edit/fpdf_edit_create.cpp @@ -1244,12 +1244,10 @@ int32_t CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { m_ObjectOffset[objnum] = 0; return 0; } - if (WriteIndirectObj(pObj)) { + if (WriteIndirectObj(pObj)) return -1; - } - if (!bExistInMap) { - m_pDocument->ReleaseIndirectObject(objnum); - } + if (!bExistInMap) + m_pDocument->DeleteIndirectObject(objnum); } else { uint8_t* pBuffer; uint32_t size; diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp index 5f1f561ebb..0114c680f2 100644 --- a/core/fpdfapi/page/cpdf_docpagedata.cpp +++ b/core/fpdfapi/page/cpdf_docpagedata.cpp @@ -175,7 +175,8 @@ CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName, return fontData->AddRef(); } - CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPDFDoc->GetByteStringPool()); + CPDF_Dictionary* pDict = + m_pPDFDoc->AddIndirectDictionary(m_pPDFDoc->GetByteStringPool()); pDict->SetNameFor("Type", "Font"); pDict->SetNameFor("Subtype", "Type1"); pDict->SetNameFor("BaseFont", fontName); @@ -183,7 +184,6 @@ CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName, pDict->SetFor("Encoding", pEncoding->Realize(m_pPDFDoc->GetByteStringPool())); } - m_pPDFDoc->AddIndirectObject(pDict); std::unique_ptr pFont = CPDF_Font::Create(m_pPDFDoc, pDict); if (!pFont) return nullptr; diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp index 50768c5058..2755381de4 100644 --- a/core/fpdfapi/page/cpdf_image.cpp +++ b/core/fpdfapi/page/cpdf_image.cpp @@ -204,7 +204,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { } else if (bpp == 8) { int32_t iPalette = pBitmap->GetPaletteSize(); if (iPalette > 0) { - CPDF_Array* pCS = new CPDF_Array; + UniqueArray pCS(new CPDF_Array); pCS->AddName("Indexed"); pCS->AddName("DeviceRGB"); pCS->AddInteger(iPalette - 1); @@ -217,12 +217,12 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { ptr[2] = (uint8_t)argb; ptr += 3; } - CPDF_Stream* pCTS = new CPDF_Stream( + CPDF_Stream* pCTS = m_pDocument->AddIndirectStream( pColorTable, iPalette * 3, new CPDF_Dictionary(m_pDocument->GetByteStringPool())); - pCS->AddReference(m_pDocument, m_pDocument->AddIndirectObject(pCTS)); + pCS->AddReference(m_pDocument, pCTS->GetObjNum()); pDict->SetReferenceFor("ColorSpace", m_pDocument, - m_pDocument->AddIndirectObject(pCS)); + m_pDocument->AddIndirectObject(std::move(pCS))); } else { pDict->SetNameFor("ColorSpace", "DeviceGray"); } @@ -274,9 +274,9 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { } } pMaskDict->SetIntegerFor("Length", mask_size); - pDict->SetReferenceFor("SMask", m_pDocument, - m_pDocument->AddIndirectObject(new CPDF_Stream( - mask_buf, mask_size, pMaskDict))); + pDict->SetReferenceFor( + "SMask", m_pDocument, + m_pDocument->AddIndirectStream(mask_buf, mask_size, pMaskDict)); if (bDeleteMask) delete pMaskBitmap; } diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp index a1518dfed0..1239fcd3ce 100644 --- a/core/fpdfapi/parser/cfdf_document.cpp +++ b/core/fpdfapi/parser/cfdf_document.cpp @@ -26,8 +26,7 @@ CFDF_Document::~CFDF_Document() { CFDF_Document* CFDF_Document::CreateNewDoc() { CFDF_Document* pDoc = new CFDF_Document; - pDoc->m_pRootDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); - pDoc->AddIndirectObject(pDoc->m_pRootDict); + pDoc->m_pRootDict = pDoc->AddIndirectDictionary(pDoc->GetByteStringPool()); pDoc->m_pRootDict->SetFor("FDF", new CPDF_Dictionary(pDoc->GetByteStringPool())); return pDoc; @@ -69,7 +68,8 @@ void CFDF_Document::ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile) { if (!pObj) break; - ReplaceIndirectObjectIfHigherGeneration(objnum, pObj); + // TODO(tsepez): check |pObj| ownership. + ReplaceIndirectObjectIfHigherGeneration(objnum, UniqueObject(pObj)); word = parser.GetNextWord(nullptr); if (word != "endobj") break; diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp index 807f62d7f3..db3b18be3e 100644 --- a/core/fpdfapi/parser/cpdf_array.cpp +++ b/core/fpdfapi/parser/cpdf_array.cpp @@ -152,8 +152,9 @@ void CPDF_Array::ConvertToIndirectObjectAt(size_t i, if (!m_Objects[i] || m_Objects[i]->IsReference()) return; - uint32_t dwObjNum = pHolder->AddIndirectObject(m_Objects[i].release()); - m_Objects[i] = UniqueObject(new CPDF_Reference(pHolder, dwObjNum)); + CPDF_Object* pUnowned = pHolder->AddIndirectObject(std::move(m_Objects[i])); + m_Objects[i] = + UniqueObject(new CPDF_Reference(pHolder, pUnowned->GetObjNum())); } void CPDF_Array::SetAt(size_t i, CPDF_Object* pObj) { @@ -205,3 +206,8 @@ void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum) { Add(new CPDF_Reference(pDoc, objnum)); } + +void CPDF_Array::AddReference(CPDF_IndirectObjectHolder* pDoc, + const CPDF_Object* pObj) { + AddReference(pDoc, pObj->GetObjNum()); +} diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h index f473e26800..18f1c00753 100644 --- a/core/fpdfapi/parser/cpdf_array.h +++ b/core/fpdfapi/parser/cpdf_array.h @@ -54,6 +54,7 @@ class CPDF_Array : public CPDF_Object { void AddString(const CFX_ByteString& str); void AddName(const CFX_ByteString& str); void AddReference(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum); + void AddReference(CPDF_IndirectObjectHolder* pDoc, const CPDF_Object* pObj); iterator begin() { return m_Objects.begin(); } iterator end() { return m_Objects.end(); } diff --git a/core/fpdfapi/parser/cpdf_array_unittest.cpp b/core/fpdfapi/parser/cpdf_array_unittest.cpp index bc9f578021..a3a27fc4ce 100644 --- a/core/fpdfapi/parser/cpdf_array_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_array_unittest.cpp @@ -113,10 +113,11 @@ TEST(cpdf_array, Clone) { for (size_t i = 0; i < kNumOfRows; ++i) { CPDF_Array* arr_elem = new CPDF_Array; for (size_t j = 0; j < kNumOfRowElems; ++j) { - CPDF_Number* obj = new CPDF_Number(elems[i][j]); - // Starts object number from 1. + UniqueObject obj(new CPDF_Number(elems[i][j])); + // Object number starts from 1. int obj_num = i * kNumOfRowElems + j + 1; - obj_holder->ReplaceIndirectObjectIfHigherGeneration(obj_num, obj); + obj_holder->ReplaceIndirectObjectIfHigherGeneration(obj_num, + std::move(obj)); arr_elem->InsertAt(j, new CPDF_Reference(obj_holder.get(), obj_num)); } arr->InsertAt(i, arr_elem); diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp index 980c94d325..9629c204bb 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/parser/cpdf_data_avail.cpp @@ -1771,8 +1771,9 @@ CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) { if (!pPageDict) return nullptr; - if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration(dwObjNum, - pPageDict)) { + // TODO(tsepez): check |pPageDict| ownership. + if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration( + dwObjNum, UniqueObject(pPageDict))) { return nullptr; } return pPageDict->GetDict(); diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp index 435eee7248..0f03947ebd 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.cpp +++ b/core/fpdfapi/parser/cpdf_dictionary.cpp @@ -188,8 +188,8 @@ void CPDF_Dictionary::ConvertToIndirectObjectFor( if (it == m_Map.end() || it->second->IsReference()) return; - uint32_t objnum = pHolder->AddIndirectObject(it->second.release()); - it->second = UniqueReference(new CPDF_Reference(pHolder, objnum)); + CPDF_Object* pObj = pHolder->AddIndirectObject(std::move(it->second)); + it->second = UniqueReference(new CPDF_Reference(pHolder, pObj->GetObjNum())); } void CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) { @@ -229,6 +229,12 @@ void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key, SetFor(key, new CPDF_Reference(pDoc, objnum)); } +void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key, + CPDF_IndirectObjectHolder* pDoc, + const CPDF_Object* pObj) { + SetReferenceFor(key, pDoc, pObj->GetObjNum()); +} + void CPDF_Dictionary::SetNumberFor(const CFX_ByteString& key, FX_FLOAT f) { SetFor(key, new CPDF_Number(f)); } diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h index 6265522997..3e55812794 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.h +++ b/core/fpdfapi/parser/cpdf_dictionary.h @@ -67,6 +67,9 @@ class CPDF_Dictionary : public CPDF_Object { void SetReferenceFor(const CFX_ByteString& key, CPDF_IndirectObjectHolder* pDoc, uint32_t objnum); + void SetReferenceFor(const CFX_ByteString& key, + CPDF_IndirectObjectHolder* pDoc, + const CPDF_Object* objnum); void SetRectFor(const CFX_ByteString& key, const CFX_FloatRect& rect); void SetMatrixFor(const CFX_ByteString& key, const CFX_Matrix& matrix); void SetBooleanFor(const CFX_ByteString& key, bool bValue); diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index c5f64a790c..fdd395e351 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp @@ -256,7 +256,7 @@ int InsertDeletePDFPage(CPDF_Document* pDoc, if (nPagesToGo == 0) { if (bInsert) { pKidList->InsertAt(i, new CPDF_Reference(pDoc, pPage->GetObjNum())); - pPage->SetReferenceFor("Parent", pDoc, pPages->GetObjNum()); + pPage->SetReferenceFor("Parent", pDoc, pPages); } else { pKidList->RemoveAt(i); } @@ -307,7 +307,7 @@ int InsertNewPage(CPDF_Document* pDoc, } pPagesList->Add(new CPDF_Reference(pDoc, pPageDict->GetObjNum())); pPages->SetIntegerFor("Count", nPages + 1); - pPageDict->SetReferenceFor("Parent", pDoc, pPages->GetObjNum()); + pPageDict->SetReferenceFor("Parent", pDoc, pPages); } else { std::set stack = {pPages}; if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, &stack) < 0) @@ -693,25 +693,23 @@ CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) { void CPDF_Document::CreateNewDoc() { ASSERT(!m_pRootDict && !m_pInfoDict); - m_pRootDict = new CPDF_Dictionary(m_pByteStringPool); + m_pRootDict = AddIndirectDictionary(m_pByteStringPool); m_pRootDict->SetNameFor("Type", "Catalog"); - AddIndirectObject(m_pRootDict); - CPDF_Dictionary* pPages = new CPDF_Dictionary(m_pByteStringPool); + CPDF_Dictionary* pPages = AddIndirectDictionary(m_pByteStringPool); pPages->SetNameFor("Type", "Pages"); pPages->SetNumberFor("Count", 0); pPages->SetFor("Kids", new CPDF_Array); - m_pRootDict->SetReferenceFor("Pages", this, AddIndirectObject(pPages)); - m_pInfoDict = new CPDF_Dictionary(m_pByteStringPool); - AddIndirectObject(m_pInfoDict); + + m_pRootDict->SetReferenceFor("Pages", this, pPages); + m_pInfoDict = AddIndirectDictionary(m_pByteStringPool); } CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) { - CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pByteStringPool); + CPDF_Dictionary* pDict = AddIndirectDictionary(m_pByteStringPool); pDict->SetNameFor("Type", "Page"); - uint32_t dwObjNum = AddIndirectObject(pDict); if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) { - ReleaseIndirectObject(dwObjNum); + DeleteIndirectObject(pDict->GetObjNum()); return nullptr; } return pDict; @@ -750,7 +748,8 @@ size_t CPDF_Document::CalculateEncodingDict(int charset, } if (i == FX_ArraySize(g_FX_CharsetUnicodes)) return i; - CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary(m_pByteStringPool); + + CPDF_Dictionary* pEncodingDict = AddIndirectDictionary(m_pByteStringPool); pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); CPDF_Array* pArray = new CPDF_Array; pArray->AddInteger(128); @@ -760,9 +759,7 @@ size_t CPDF_Document::CalculateEncodingDict(int charset, pArray->AddName(name.IsEmpty() ? ".notdef" : name); } pEncodingDict->SetFor("Differences", pArray); - pBaseDict->SetReferenceFor("Encoding", this, - AddIndirectObject(pEncodingDict)); - + pBaseDict->SetReferenceFor("Encoding", this, pEncodingDict); return i; } @@ -772,7 +769,7 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK( FX_BOOL bVert, CFX_ByteString basefont, std::function Insert) { - CPDF_Dictionary* pFontDict = new CPDF_Dictionary(m_pByteStringPool); + CPDF_Dictionary* pFontDict = AddIndirectDictionary(m_pByteStringPool); CFX_ByteString cmap; CFX_ByteString ordering; int supplement = 0; @@ -822,14 +819,17 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK( pFontDict->SetNameFor("Type", "Font"); pFontDict->SetNameFor("Subtype", "CIDFontType2"); pFontDict->SetNameFor("BaseFont", basefont); + CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary(m_pByteStringPool); pCIDSysInfo->SetStringFor("Registry", "Adobe"); pCIDSysInfo->SetStringFor("Ordering", ordering); pCIDSysInfo->SetIntegerFor("Supplement", supplement); pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo); + CPDF_Array* pArray = new CPDF_Array; pBaseDict->SetFor("DescendantFonts", pArray); - pArray->AddReference(this, AddIndirectObject(pFontDict)); + + pArray->AddReference(this, pFontDict); return pFontDict; } @@ -847,7 +847,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(), false, false, charset == FXFONT_SYMBOL_CHARSET); - CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool); + CPDF_Dictionary* pBaseDict = AddIndirectDictionary(m_pByteStringPool); pBaseDict->SetNameFor("Type", "Font"); std::unique_ptr pEncoding( new CFX_UnicodeEncoding(pFont)); @@ -888,7 +888,6 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { end, widthArr); }); } - AddIndirectObject(pBaseDict); int italicangle = pFont->GetSubstFont() ? pFont->GetSubstFont()->m_ItalicAngle : 0; FX_RECT bbox; @@ -916,8 +915,11 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { CPDF_Dictionary* pFontDesc = CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(), pFont->GetDescent(), pBBox, nStemV); + + // TODO(tsepez): check |pFontDesc| ownership. pFontDict->SetReferenceFor("FontDescriptor", this, - AddIndirectObject(pFontDesc)); + AddIndirectObject(UniqueDictionary(pFontDesc))); + return LoadFont(pBaseDict); } @@ -979,7 +981,7 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, ptm->otmrcFontBox.right, ptm->otmrcFontBox.top}; FX_Free(tm_buf); basefont.Replace(" ", ""); - CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool); + CPDF_Dictionary* pBaseDict = AddIndirectDictionary(m_pByteStringPool); pBaseDict->SetNameFor("Type", "Font"); CPDF_Dictionary* pFontDict = pBaseDict; if (!bCJK) { @@ -1004,7 +1006,6 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, InsertWidthArray(hDC, start, end, widthArr); }); } - AddIndirectObject(pBaseDict); CPDF_Array* pBBox = new CPDF_Array; for (int i = 0; i < 4; i++) pBBox->AddInteger(bbox[i]); @@ -1012,8 +1013,11 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend, pBBox, pLogFont->lfWeight / 5); pFontDesc->SetIntegerFor("CapHeight", capheight); + + // TODO(tsepez): check |pFontDesc| ownership. pFontDict->SetReferenceFor("FontDescriptor", this, - AddIndirectObject(pFontDesc)); + AddIndirectObject(UniqueObject(pFontDesc))); + hFont = SelectObject(hDC, hFont); DeleteObject(hFont); DeleteDC(hDC); diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp index 6e549de5a7..49567e50a1 100644 --- a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp +++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp @@ -6,8 +6,11 @@ #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h" +#include "core/fpdfapi/parser/cpdf_array.h" +#include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_object.h" #include "core/fpdfapi/parser/cpdf_parser.h" +#include "core/fpdfapi/parser/cpdf_stream.h" CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder() : m_LastObjNum(0) {} @@ -42,35 +45,59 @@ CPDF_Object* CPDF_IndirectObjectHolder::ParseIndirectObject(uint32_t objnum) { return nullptr; } -uint32_t CPDF_IndirectObjectHolder::AddIndirectObject(CPDF_Object* pObj) { +CPDF_Object* CPDF_IndirectObjectHolder::AddIndirectObject(UniqueObject pObj) { if (pObj->m_ObjNum) - return pObj->m_ObjNum; + return pObj.release(); // TODO(tsepez): shouldn't happen, stop this leak. - m_LastObjNum++; + pObj->m_ObjNum = ++m_LastObjNum; m_IndirectObjs[m_LastObjNum].release(); // TODO(tsepez): stop this leak. - m_IndirectObjs[m_LastObjNum].reset(pObj); - pObj->m_ObjNum = m_LastObjNum; - return m_LastObjNum; + m_IndirectObjs[m_LastObjNum].reset(pObj.release()); // Changes deleters. + return m_IndirectObjs[m_LastObjNum].get(); +} + +CPDF_Array* CPDF_IndirectObjectHolder::AddIndirectArray() { + return ToArray(AddIndirectObject(UniqueObject(new CPDF_Array()))); +} + +CPDF_Dictionary* CPDF_IndirectObjectHolder::AddIndirectDictionary() { + return ToDictionary(AddIndirectObject(UniqueObject(new CPDF_Dictionary()))); +} + +CPDF_Dictionary* CPDF_IndirectObjectHolder::AddIndirectDictionary( + const CFX_WeakPtr& pPool) { + return ToDictionary( + AddIndirectObject(UniqueObject(new CPDF_Dictionary(pPool)))); +} + +CPDF_Stream* CPDF_IndirectObjectHolder::AddIndirectStream() { + return ToStream(AddIndirectObject(UniqueObject(new CPDF_Stream()))); +} + +CPDF_Stream* CPDF_IndirectObjectHolder::AddIndirectStream( + uint8_t* pData, + uint32_t size, + CPDF_Dictionary* pDict) { + return ToStream( + AddIndirectObject(UniqueObject(new CPDF_Stream(pData, size, pDict)))); } bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration( uint32_t objnum, - CPDF_Object* pObj) { + UniqueObject pObj) { if (!objnum || !pObj) return false; CPDF_Object* pOldObj = GetIndirectObject(objnum); - if (pOldObj && pObj->GetGenNum() <= pOldObj->GetGenNum()) { - delete pObj; + if (pOldObj && pObj->GetGenNum() <= pOldObj->GetGenNum()) return false; - } + pObj->m_ObjNum = objnum; - m_IndirectObjs[objnum].reset(pObj); + m_IndirectObjs[objnum].reset(pObj.release()); // Changes deleters. m_LastObjNum = std::max(m_LastObjNum, objnum); return true; } -void CPDF_IndirectObjectHolder::ReleaseIndirectObject(uint32_t objnum) { +void CPDF_IndirectObjectHolder::DeleteIndirectObject(uint32_t objnum) { CPDF_Object* pObj = GetIndirectObject(objnum); if (!pObj || pObj->GetObjNum() == CPDF_Object::kInvalidObjNum) return; diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.h b/core/fpdfapi/parser/cpdf_indirect_object_holder.h index da4e942b5d..074e428d43 100644 --- a/core/fpdfapi/parser/cpdf_indirect_object_holder.h +++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.h @@ -10,9 +10,14 @@ #include #include +#include "core/fpdfapi/parser/cpdf_object.h" +#include "core/fxcrt/cfx_string_pool_template.h" +#include "core/fxcrt/cfx_weak_ptr.h" #include "core/fxcrt/fx_system.h" -class CPDF_Object; +class CPDF_Array; +class CPDF_Dictionary; +class CPDF_Stream; class CPDF_IndirectObjectHolder { public: @@ -24,12 +29,23 @@ class CPDF_IndirectObjectHolder { CPDF_Object* GetIndirectObject(uint32_t objnum) const; CPDF_Object* GetOrParseIndirectObject(uint32_t objnum); - void ReleaseIndirectObject(uint32_t objnum); + void DeleteIndirectObject(uint32_t objnum); + + // Take ownership of |pObj|, returns unowned pointer to it. + CPDF_Object* AddIndirectObject(UniqueObject pObj); + + // Adds and owns a new object, returns unowned pointer to it. + CPDF_Array* AddIndirectArray(); + CPDF_Dictionary* AddIndirectDictionary(); + CPDF_Dictionary* AddIndirectDictionary( + const CFX_WeakPtr& pPool); + CPDF_Stream* AddIndirectStream(); + CPDF_Stream* AddIndirectStream(uint8_t* pData, + uint32_t size, + CPDF_Dictionary* pDict); - // Take ownership of |pObj|. - uint32_t AddIndirectObject(CPDF_Object* pObj); bool ReplaceIndirectObjectIfHigherGeneration(uint32_t objnum, - CPDF_Object* pObj); + UniqueObject pObj); uint32_t GetLastObjNum() const { return m_LastObjNum; } void SetLastObjNum(uint32_t objnum) { m_LastObjNum = objnum; } @@ -42,6 +58,8 @@ class CPDF_IndirectObjectHolder { private: uint32_t m_LastObjNum; + + // Ordinary deleter, not Release(). std::map> m_IndirectObjs; }; diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp index e5a5f54915..b47a06fbfc 100644 --- a/core/fpdfapi/parser/cpdf_object_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp @@ -101,7 +101,7 @@ class PDFObjectsTest : public testing::Test { m_ArrayObj->Clone(), m_DictObj->Clone(), stream_obj->Clone()}; for (size_t i = 0; i < m_IndirectObjs.size(); ++i) { - m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]); + m_ObjHolder->AddIndirectObject(UniqueObject(m_IndirectObjs[i])); m_RefObjs.emplace_back(new CPDF_Reference( m_ObjHolder.get(), m_IndirectObjs[i]->GetObjNum())); } @@ -730,8 +730,8 @@ TEST(PDFArrayTest, AddReferenceAndGetObjectAt) { // Create two arrays of references by different AddReference() APIs. for (size_t i = 0; i < FX_ArraySize(indirect_objs); ++i) { // All the indirect objects inserted will be owned by holder. - holder->ReplaceIndirectObjectIfHigherGeneration(obj_nums[i], - indirect_objs[i]); + holder->ReplaceIndirectObjectIfHigherGeneration( + obj_nums[i], UniqueObject(indirect_objs[i])); arr->AddReference(holder.get(), obj_nums[i]); arr1->AddReference(holder.get(), indirect_objs[i]->GetObjNum()); } @@ -841,9 +841,8 @@ TEST(PDFObjectTest, CloneCheckLoop) { { CPDF_IndirectObjectHolder objects_holder; // Create an object with a reference loop. - CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); + CPDF_Dictionary* dict_obj = objects_holder.AddIndirectDictionary(); CPDF_Array* arr_obj = new CPDF_Array; - objects_holder.AddIndirectObject(dict_obj); EXPECT_EQ(1u, dict_obj->GetObjNum()); dict_obj->SetFor("arr", arr_obj); arr_obj->InsertAt( diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index 40a615fa47..d9c892f133 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -955,21 +955,18 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() { } FX_BOOL CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, FX_BOOL bMainXRef) { - std::unique_ptr pObject( - ParseIndirectObjectAt(m_pDocument, *pos, 0)); + UniqueObject pObject(ParseIndirectObjectAt(m_pDocument, *pos, 0)); if (!pObject) return FALSE; CPDF_Object* pUnownedObject = pObject.get(); - if (m_pDocument) { CPDF_Dictionary* pRootDict = m_pDocument->GetRoot(); if (pRootDict && pRootDict->GetObjNum() == pObject->m_ObjNum) return FALSE; - // Takes ownership of object (std::move someday). uint32_t objnum = pObject->m_ObjNum; if (!m_pDocument->ReplaceIndirectObjectIfHigherGeneration( - objnum, pObject.release())) { + objnum, std::move(pObject))) { return FALSE; } } -- cgit v1.2.3