From d5bd8a16565bbee05bfb8a8409f3ba90c461da0e Mon Sep 17 00:00:00 2001 From: tsepez Date: Mon, 17 Oct 2016 11:13:54 -0700 Subject: Revert "Make CPDF_Object containers hold objects via unique pointers." This reverts commit 1d023881cd53485303c0fcc0b5878e700dc470fd. Reason for revert -- fuzzers hit issues. TBR=thestig@chromium.org Review-Url: https://codereview.chromium.org/2425783002 --- core/fpdfapi/edit/fpdf_edit_create.cpp | 8 ++-- core/fpdfapi/page/cpdf_allstates.cpp | 2 +- core/fpdfapi/page/cpdf_colorspace.cpp | 2 +- core/fpdfapi/page/fpdf_page_parser.cpp | 2 +- core/fpdfapi/parser/cpdf_array.cpp | 44 ++++++++++--------- core/fpdfapi/parser/cpdf_array.h | 7 ++- core/fpdfapi/parser/cpdf_data_avail.cpp | 8 ++-- core/fpdfapi/parser/cpdf_dictionary.cpp | 64 +++++++++++++++++++--------- core/fpdfapi/parser/cpdf_dictionary.h | 6 +-- core/fpdfapi/parser/cpdf_object_unittest.cpp | 2 +- core/fpdfapi/parser/cpdf_parser.cpp | 2 +- core/fpdfapi/parser/cpdf_reference.h | 3 -- core/fpdfapi/parser/cpdf_stream.h | 2 +- core/fpdfapi/parser/fpdf_parser_utility.cpp | 2 +- core/fpdfdoc/cpdf_formcontrol.cpp | 4 +- core/fpdfdoc/cpdf_formfield.cpp | 2 +- core/fpdfdoc/cpdf_interform.cpp | 6 +-- 17 files changed, 95 insertions(+), 71 deletions(-) (limited to 'core') diff --git a/core/fpdfapi/edit/fpdf_edit_create.cpp b/core/fpdfapi/edit/fpdf_edit_create.cpp index fae2b14449..e5b1fe1bb0 100644 --- a/core/fpdfapi/edit/fpdf_edit_create.cpp +++ b/core/fpdfapi/edit/fpdf_edit_create.cpp @@ -128,7 +128,7 @@ int32_t PDF_CreatorAppendObject(const CPDF_Object* pObj, const CPDF_Dictionary* p = pObj->AsDictionary(); for (const auto& it : *p) { const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second.get(); + CPDF_Object* pValue = it.second; if (pFile->AppendString("/") < 0) { return -1; } @@ -197,7 +197,7 @@ int32_t PDF_CreatorWriteTrailer(CPDF_Document* pDocument, CPDF_Dictionary* p = pParser->GetTrailer(); for (const auto& it : *p) { const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second.get(); + CPDF_Object* pValue = it.second; if (key == "Encrypt" || key == "Size" || key == "Filter" || key == "Index" || key == "Length" || key == "Prev" || key == "W" || key == "XRefStm" || key == "Type" || key == "ID") { @@ -1192,7 +1192,7 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, for (const auto& it : *p) { FX_BOOL bSignValue = FALSE; const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second.get(); + CPDF_Object* pValue = it.second; if (m_File.AppendString("/") < 0) { return -1; } @@ -1714,7 +1714,7 @@ int32_t CPDF_Creator::WriteDoc_Stage4(IFX_Pause* pPause) { CPDF_Dictionary* p = m_pParser->GetTrailer(); for (const auto& it : *p) { const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second.get(); + CPDF_Object* pValue = it.second; // TODO(ochang): Consolidate with similar check in // PDF_CreatorWriteTrailer. if (key == "Encrypt" || key == "Size" || key == "Filter" || diff --git a/core/fpdfapi/page/cpdf_allstates.cpp b/core/fpdfapi/page/cpdf_allstates.cpp index c00af83aa8..70de98e3f0 100644 --- a/core/fpdfapi/page/cpdf_allstates.cpp +++ b/core/fpdfapi/page/cpdf_allstates.cpp @@ -52,7 +52,7 @@ void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser) { for (const auto& it : *pGS) { const CFX_ByteString& key_str = it.first; - CPDF_Object* pElement = it.second.get(); + CPDF_Object* pElement = it.second; CPDF_Object* pObject = pElement ? pElement->GetDirect() : nullptr; if (!pObject) continue; diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp index 12af11e7d4..fe840d10df 100644 --- a/core/fpdfapi/page/cpdf_colorspace.cpp +++ b/core/fpdfapi/page/cpdf_colorspace.cpp @@ -345,7 +345,7 @@ std::unique_ptr CPDF_ColorSpace::Load(CPDF_Document* pDoc, for (const auto& it : *pDict) { std::unique_ptr pRet; - CPDF_Object* pValue = it.second.get(); + CPDF_Object* pValue = it.second; if (ToName(pValue)) pRet.reset(ColorspaceFromName(pValue->GetString())); if (pRet) diff --git a/core/fpdfapi/page/fpdf_page_parser.cpp b/core/fpdfapi/page/fpdf_page_parser.cpp index e27872a538..b6f0bc605c 100644 --- a/core/fpdfapi/page/fpdf_page_parser.cpp +++ b/core/fpdfapi/page/fpdf_page_parser.cpp @@ -97,7 +97,7 @@ void PDF_ReplaceAbbr(CPDF_Object* pObj) { std::vector replacements; for (const auto& it : *pDict) { CFX_ByteString key = it.first; - CPDF_Object* value = it.second.get(); + CPDF_Object* value = it.second; CFX_ByteStringC fullname = PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), key.AsStringC()); diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp index 807f62d7f3..1aec3e06f3 100644 --- a/core/fpdfapi/parser/cpdf_array.cpp +++ b/core/fpdfapi/parser/cpdf_array.cpp @@ -20,11 +20,11 @@ CPDF_Array::CPDF_Array() {} CPDF_Array::~CPDF_Array() { // Mark the object as deleted so that it will not be deleted again - // in case of cyclic references, then break cycles. + // in case of cyclic references. m_ObjNum = kInvalidObjNum; for (auto& it : m_Objects) { - if (it && it->GetObjNum() == kInvalidObjNum) - it.release(); + if (it && it->GetObjNum() != kInvalidObjNum) + it->Release(); } } @@ -53,11 +53,10 @@ CPDF_Object* CPDF_Array::CloneNonCyclic( std::set* pVisited) const { pVisited->insert(this); CPDF_Array* pCopy = new CPDF_Array(); - for (const auto& pObj : m_Objects) { - if (!pdfium::ContainsKey(*pVisited, pObj.get())) { - pCopy->m_Objects.push_back( - UniqueObject(pObj->CloneNonCyclic(bDirect, pVisited))); - } + for (size_t i = 0; i < GetCount(); i++) { + CPDF_Object* value = m_Objects[i]; + if (!pdfium::ContainsKey(*pVisited, value)) + pCopy->m_Objects.push_back(value->CloneNonCyclic(bDirect, pVisited)); } return pCopy; } @@ -87,7 +86,7 @@ CFX_Matrix CPDF_Array::GetMatrix() { CPDF_Object* CPDF_Array::GetObjectAt(size_t i) const { if (i >= m_Objects.size()) return nullptr; - return m_Objects[i].get(); + return m_Objects[i]; } CPDF_Object* CPDF_Array::GetDirectObjectAt(size_t i) const { @@ -140,8 +139,11 @@ void CPDF_Array::RemoveAt(size_t i, size_t nCount) { if (nCount <= 0 || nCount > m_Objects.size() - i) return; - auto it = m_Objects.begin() + i; - m_Objects.erase(it, it + nCount); + for (size_t j = 0; j < nCount; ++j) { + if (CPDF_Object* p = m_Objects[i + j]) + p->Release(); + } + m_Objects.erase(m_Objects.begin() + i, m_Objects.begin() + i + nCount); } void CPDF_Array::ConvertToIndirectObjectAt(size_t i, @@ -149,11 +151,12 @@ void CPDF_Array::ConvertToIndirectObjectAt(size_t i, if (i >= m_Objects.size()) return; - if (!m_Objects[i] || m_Objects[i]->IsReference()) + CPDF_Object* pObj = m_Objects[i]; + if (!pObj || pObj->IsReference()) return; - uint32_t dwObjNum = pHolder->AddIndirectObject(m_Objects[i].release()); - m_Objects[i] = UniqueObject(new CPDF_Reference(pHolder, dwObjNum)); + uint32_t dwObjNum = pHolder->AddIndirectObject(pObj); + m_Objects[i] = new CPDF_Reference(pHolder, dwObjNum); } void CPDF_Array::SetAt(size_t i, CPDF_Object* pObj) { @@ -163,7 +166,10 @@ void CPDF_Array::SetAt(size_t i, CPDF_Object* pObj) { ASSERT(false); return; } - m_Objects[i] = UniqueObject(pObj); + if (CPDF_Object* pOld = m_Objects[i]) + pOld->Release(); + + m_Objects[i] = pObj; } void CPDF_Array::InsertAt(size_t index, CPDF_Object* pObj) { @@ -171,18 +177,18 @@ void CPDF_Array::InsertAt(size_t index, CPDF_Object* pObj) { CHECK(!pObj || pObj->IsInline()); if (index >= m_Objects.size()) { // Allocate space first. - m_Objects.resize(index + 1); - m_Objects[index] = UniqueObject(pObj); + m_Objects.resize(index + 1, nullptr); + m_Objects[index] = pObj; } else { // Directly insert. - m_Objects.insert(m_Objects.begin() + index, UniqueObject(pObj)); + m_Objects.insert(m_Objects.begin() + index, pObj); } } void CPDF_Array::Add(CPDF_Object* pObj) { ASSERT(IsArray()); CHECK(!pObj || pObj->IsInline()); - m_Objects.push_back(UniqueObject(pObj)); + m_Objects.push_back(pObj); } void CPDF_Array::AddName(const CFX_ByteString& str) { diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h index f473e26800..8cfa0333bb 100644 --- a/core/fpdfapi/parser/cpdf_array.h +++ b/core/fpdfapi/parser/cpdf_array.h @@ -17,8 +17,8 @@ class CPDF_Array : public CPDF_Object { public: - using iterator = std::vector::iterator; - using const_iterator = std::vector::const_iterator; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; CPDF_Array(); @@ -67,9 +67,8 @@ class CPDF_Array : public CPDF_Object { bool bDirect, std::set* pVisited) const override; - std::vector m_Objects; + std::vector m_Objects; }; - using UniqueArray = std::unique_ptr>; inline CPDF_Array* ToArray(CPDF_Object* obj) { diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp index 980c94d325..e23aa8ecfb 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/parser/cpdf_data_avail.cpp @@ -155,7 +155,7 @@ FX_BOOL CPDF_DataAvail::AreObjectsAvailable( for (const auto& it : *pDict) { const CFX_ByteString& key = it.first; - CPDF_Object* value = it.second.get(); + CPDF_Object* value = it.second; if (key != "Parent") new_obj_array.push_back(value); } @@ -493,8 +493,8 @@ FX_BOOL CPDF_DataAvail::CheckPage(DownloadHints* pHints) { CPDF_Array* pArray = ToArray(pObj); if (pArray) { - for (auto& pArrayObj : *pArray) { - if (CPDF_Reference* pRef = ToReference(pArrayObj.get())) + for (CPDF_Object* pArrayObj : *pArray) { + if (CPDF_Reference* pRef = ToReference(pArrayObj)) UnavailObjList.Add(pRef->GetRefObjNum()); } } @@ -742,7 +742,7 @@ FX_BOOL CPDF_DataAvail::CheckHintTables(DownloadHints* pHints) { return FALSE; } - for (const auto& pArrayObject : *pHintStreamRange) { + for (const CPDF_Object* pArrayObject : *pHintStreamRange) { const CPDF_Number* pNumber = ToNumber(pArrayObject->GetDirect()); if (!pNumber || !pNumber->IsInteger()) { m_docStatus = PDF_DATAAVAIL_ERROR; diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp index 435eee7248..aab7422b3c 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.cpp +++ b/core/fpdfapi/parser/cpdf_dictionary.cpp @@ -27,11 +27,11 @@ CPDF_Dictionary::CPDF_Dictionary(const CFX_WeakPtr& pPool) CPDF_Dictionary::~CPDF_Dictionary() { // Mark the object as deleted so that it will not be deleted again - // in case of cyclic references, then break cycles. + // in case of cyclic references. m_ObjNum = kInvalidObjNum; - for (auto& it : m_Map) { - if (it.second && it.second->GetObjNum() == kInvalidObjNum) - it.second.release(); + for (const auto& it : m_Map) { + if (it.second && it.second->GetObjNum() != kInvalidObjNum) + it.second->Release(); } } @@ -65,19 +65,20 @@ CPDF_Object* CPDF_Dictionary::CloneNonCyclic( bool bDirect, std::set* pVisited) const { pVisited->insert(this); - UniqueDictionary pCopy = UniqueDictionary(new CPDF_Dictionary(m_pPool)); + CPDF_Dictionary* pCopy = new CPDF_Dictionary(m_pPool); for (const auto& it : *this) { - if (!pdfium::ContainsKey(*pVisited, it.second.get())) { - pCopy->m_Map[it.first] = - UniqueObject(it.second->CloneNonCyclic(bDirect, pVisited)); + CPDF_Object* value = it.second; + if (!pdfium::ContainsKey(*pVisited, value)) { + pCopy->m_Map.insert( + std::make_pair(it.first, value->CloneNonCyclic(bDirect, pVisited))); } } - return pCopy.release(); + return pCopy; } CPDF_Object* CPDF_Dictionary::GetObjectFor(const CFX_ByteString& key) const { auto it = m_Map.find(key); - return it != m_Map.end() ? it->second.get() : nullptr; + return it != m_Map.end() ? it->second : nullptr; } CPDF_Object* CPDF_Dictionary::GetDirectObjectFor( @@ -173,12 +174,22 @@ bool CPDF_Dictionary::IsSignatureDict() const { } void CPDF_Dictionary::SetFor(const CFX_ByteString& key, CPDF_Object* pObj) { - if (!pObj) { - m_Map.erase(key); + CHECK(!pObj || pObj->IsInline()); + auto it = m_Map.find(key); + if (it == m_Map.end()) { + if (pObj) + m_Map.insert(std::make_pair(MaybeIntern(key), pObj)); return; } - ASSERT(pObj->IsInline()); - m_Map[key] = UniqueObject(pObj); + + if (it->second == pObj) + return; + it->second->Release(); + + if (pObj) + it->second = pObj; + else + m_Map.erase(it); } void CPDF_Dictionary::ConvertToIndirectObjectFor( @@ -188,24 +199,35 @@ 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)); + uint32_t objnum = pHolder->AddIndirectObject(it->second); + it->second = new CPDF_Reference(pHolder, objnum); } void CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) { - m_Map.erase(key); + auto it = m_Map.find(key); + if (it == m_Map.end()) + return; + + it->second->Release(); + m_Map.erase(it); } void CPDF_Dictionary::ReplaceKey(const CFX_ByteString& oldkey, const CFX_ByteString& newkey) { - if (oldkey == newkey) - return; - auto old_it = m_Map.find(oldkey); if (old_it == m_Map.end()) return; - m_Map[newkey] = std::move(old_it->second); + auto new_it = m_Map.find(newkey); + if (new_it == old_it) + return; + + if (new_it != m_Map.end()) { + new_it->second->Release(); + new_it->second = old_it->second; + } else { + m_Map.insert(std::make_pair(MaybeIntern(newkey), old_it->second)); + } m_Map.erase(old_it); } diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h index 6265522997..fb8200f78c 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.h +++ b/core/fpdfapi/parser/cpdf_dictionary.h @@ -21,8 +21,8 @@ class CPDF_IndirectObjectHolder; class CPDF_Dictionary : public CPDF_Object { public: - using iterator = std::map::iterator; - using const_iterator = std::map::const_iterator; + using iterator = std::map::iterator; + using const_iterator = std::map::const_iterator; CPDF_Dictionary(); explicit CPDF_Dictionary(const CFX_WeakPtr& pPool); @@ -96,7 +96,7 @@ class CPDF_Dictionary : public CPDF_Object { std::set* visited) const override; CFX_WeakPtr m_pPool; - std::map m_Map; + std::map m_Map; }; using UniqueDictionary = diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp index e5a5f54915..8215226ef3 100644 --- a/core/fpdfapi/parser/cpdf_object_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp @@ -139,7 +139,7 @@ class PDFObjectsTest : public testing::Test { return false; for (CPDF_Dictionary::const_iterator it = dict1->begin(); it != dict1->end(); ++it) { - if (!Equal(it->second.get(), dict2->GetObjectFor(it->first))) + if (!Equal(it->second, dict2->GetObjectFor(it->first))) return false; } return true; diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index 40a615fa47..c29ae18da2 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -826,7 +826,7 @@ FX_BOOL CPDF_Parser::RebuildCrossRef() { auto it = pTrailer->begin(); while (it != pTrailer->end()) { const CFX_ByteString& key = it->first; - CPDF_Object* pElement = it->second.get(); + CPDF_Object* pElement = it->second; ++it; uint32_t dwObjNum = pElement ? pElement->GetObjNum() : 0; diff --git a/core/fpdfapi/parser/cpdf_reference.h b/core/fpdfapi/parser/cpdf_reference.h index e9416aecad..5221832f80 100644 --- a/core/fpdfapi/parser/cpdf_reference.h +++ b/core/fpdfapi/parser/cpdf_reference.h @@ -47,9 +47,6 @@ class CPDF_Reference : public CPDF_Object { uint32_t m_RefObjNum; }; -using UniqueReference = - std::unique_ptr>; - inline CPDF_Reference* ToReference(CPDF_Object* obj) { return obj ? obj->AsReference() : nullptr; } diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h index b440f94354..756eccfba1 100644 --- a/core/fpdfapi/parser/cpdf_stream.h +++ b/core/fpdfapi/parser/cpdf_stream.h @@ -51,7 +51,7 @@ class CPDF_Stream : public CPDF_Object { bool bDirect, std::set* pVisited) const override; - UniqueDictionary m_pDict; + std::unique_ptr> m_pDict; bool m_bMemoryBased = true; uint32_t m_dwSize = 0; std::unique_ptr m_pDataBuf; diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp index 6f1ce14d6e..7b9ead4005 100644 --- a/core/fpdfapi/parser/fpdf_parser_utility.cpp +++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp @@ -193,7 +193,7 @@ CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) { buf << "<<"; for (const auto& it : *p) { const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second.get(); + CPDF_Object* pValue = it.second; buf << "/" << PDF_NameEncode(key); if (pValue && !pValue->IsInline()) { buf << " " << pValue->GetObjNum() << " 0 R "; diff --git a/core/fpdfdoc/cpdf_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp index 7bb9c832ba..d0b4a2dced 100644 --- a/core/fpdfdoc/cpdf_formcontrol.cpp +++ b/core/fpdfdoc/cpdf_formcontrol.cpp @@ -68,7 +68,7 @@ void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { return; for (const auto& it : *pAP) { - CPDF_Object* pObj1 = it.second.get(); + CPDF_Object* pObj1 = it.second; if (!pObj1) continue; @@ -80,7 +80,7 @@ void CPDF_FormControl::SetOnStateName(const CFX_ByteString& csOn) { auto subdict_it = pSubDict->begin(); while (subdict_it != pSubDict->end()) { const CFX_ByteString& csKey2 = subdict_it->first; - CPDF_Object* pObj2 = subdict_it->second.get(); + CPDF_Object* pObj2 = subdict_it->second; ++subdict_it; if (!pObj2) continue; diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp index fbe2f052c4..dc45fbcec7 100644 --- a/core/fpdfdoc/cpdf_formfield.cpp +++ b/core/fpdfdoc/cpdf_formfield.cpp @@ -839,7 +839,7 @@ FX_BOOL CPDF_FormField::IsOptionSelected(int iOptIndex) const { if (!pArray) return FALSE; - for (const auto& pObj : *pArray) { + for (CPDF_Object* pObj : *pArray) { if (pObj->GetInteger() == iOptIndex) return TRUE; } diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp index 3bef85ef9c..b8b4b68e29 100644 --- a/core/fpdfdoc/cpdf_interform.cpp +++ b/core/fpdfdoc/cpdf_interform.cpp @@ -138,7 +138,7 @@ CPDF_Font* GetNativeFont(CPDF_Dictionary* pFormDict, for (const auto& it : *pFonts) { const CFX_ByteString& csKey = it.first; - CPDF_Object* pObj = it.second.get(); + CPDF_Object* pObj = it.second; if (!pObj) continue; @@ -179,7 +179,7 @@ FX_BOOL FindFont(CPDF_Dictionary* pFormDict, for (const auto& it : *pFonts) { const CFX_ByteString& csKey = it.first; - CPDF_Object* pObj = it.second.get(); + CPDF_Object* pObj = it.second; if (!pObj) continue; @@ -216,7 +216,7 @@ FX_BOOL FindFont(CPDF_Dictionary* pFormDict, for (const auto& it : *pFonts) { const CFX_ByteString& csKey = it.first; - CPDF_Object* pObj = it.second.get(); + CPDF_Object* pObj = it.second; if (!pObj) continue; -- cgit v1.2.3