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/parser/cpdf_dictionary.cpp | 64 ++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'core/fpdfapi/parser/cpdf_dictionary.cpp') 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); } -- cgit v1.2.3