summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/cpdf_dictionary.cpp
diff options
context:
space:
mode:
authortsepez <tsepez@chromium.org>2016-10-17 11:13:54 -0700
committerCommit bot <commit-bot@chromium.org>2016-10-17 11:13:54 -0700
commitd5bd8a16565bbee05bfb8a8409f3ba90c461da0e (patch)
treea36c7a23c77ca3d2990109b419b823e801978e67 /core/fpdfapi/parser/cpdf_dictionary.cpp
parent522ed14ce8cf39e5e6fc1a58099edd4f849b7fb8 (diff)
downloadpdfium-d5bd8a16565bbee05bfb8a8409f3ba90c461da0e.tar.xz
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
Diffstat (limited to 'core/fpdfapi/parser/cpdf_dictionary.cpp')
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.cpp64
1 files changed, 43 insertions, 21 deletions
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<CFX_ByteStringPool>& 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<const CPDF_Object*>* 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);
}