summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
authortsepez <tsepez@chromium.org>2016-10-13 16:36:20 -0700
committerCommit bot <commit-bot@chromium.org>2016-10-13 16:36:20 -0700
commit1d023881cd53485303c0fcc0b5878e700dc470fd (patch)
tree0f41370ff729b0495f475887a3f6f38a0210aae4 /core/fpdfapi
parent20f8ecc2f44332792c11cf0ac566c0114712b83c (diff)
downloadpdfium-1d023881cd53485303c0fcc0b5878e700dc470fd.tar.xz
Make CPDF_Object containers hold objects via unique pointers.
This tweaks the implementation while leaving the API the same. The API change is more disruptive, so break this part off first. Review-Url: https://codereview.chromium.org/2385293002
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/edit/fpdf_edit_create.cpp8
-rw-r--r--core/fpdfapi/page/cpdf_allstates.cpp2
-rw-r--r--core/fpdfapi/page/cpdf_colorspace.cpp2
-rw-r--r--core/fpdfapi/page/fpdf_page_parser.cpp2
-rw-r--r--core/fpdfapi/parser/cpdf_array.cpp44
-rw-r--r--core/fpdfapi/parser/cpdf_array.h7
-rw-r--r--core/fpdfapi/parser/cpdf_data_avail.cpp8
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.cpp64
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.h6
-rw-r--r--core/fpdfapi/parser/cpdf_object_unittest.cpp2
-rw-r--r--core/fpdfapi/parser/cpdf_parser.cpp2
-rw-r--r--core/fpdfapi/parser/cpdf_reference.h3
-rw-r--r--core/fpdfapi/parser/cpdf_stream.h2
-rw-r--r--core/fpdfapi/parser/fpdf_parser_utility.cpp2
14 files changed, 65 insertions, 89 deletions
diff --git a/core/fpdfapi/edit/fpdf_edit_create.cpp b/core/fpdfapi/edit/fpdf_edit_create.cpp
index e5b1fe1bb0..fae2b14449 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;
+ CPDF_Object* pValue = it.second.get();
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;
+ CPDF_Object* pValue = it.second.get();
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;
+ CPDF_Object* pValue = it.second.get();
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;
+ CPDF_Object* pValue = it.second.get();
// 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 70de98e3f0..c00af83aa8 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;
+ CPDF_Object* pElement = it.second.get();
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 fe840d10df..12af11e7d4 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -345,7 +345,7 @@ std::unique_ptr<CPDF_ColorSpace> CPDF_ColorSpace::Load(CPDF_Document* pDoc,
for (const auto& it : *pDict) {
std::unique_ptr<CPDF_ColorSpace> pRet;
- CPDF_Object* pValue = it.second;
+ CPDF_Object* pValue = it.second.get();
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 b6f0bc605c..e27872a538 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<AbbrReplacementOp> replacements;
for (const auto& it : *pDict) {
CFX_ByteString key = it.first;
- CPDF_Object* value = it.second;
+ CPDF_Object* value = it.second.get();
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 1aec3e06f3..807f62d7f3 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.
+ // in case of cyclic references, then break cycles.
m_ObjNum = kInvalidObjNum;
for (auto& it : m_Objects) {
- if (it && it->GetObjNum() != kInvalidObjNum)
- it->Release();
+ if (it && it->GetObjNum() == kInvalidObjNum)
+ it.release();
}
}
@@ -53,10 +53,11 @@ CPDF_Object* CPDF_Array::CloneNonCyclic(
std::set<const CPDF_Object*>* pVisited) const {
pVisited->insert(this);
CPDF_Array* pCopy = new CPDF_Array();
- 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));
+ for (const auto& pObj : m_Objects) {
+ if (!pdfium::ContainsKey(*pVisited, pObj.get())) {
+ pCopy->m_Objects.push_back(
+ UniqueObject(pObj->CloneNonCyclic(bDirect, pVisited)));
+ }
}
return pCopy;
}
@@ -86,7 +87,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];
+ return m_Objects[i].get();
}
CPDF_Object* CPDF_Array::GetDirectObjectAt(size_t i) const {
@@ -139,11 +140,8 @@ void CPDF_Array::RemoveAt(size_t i, size_t nCount) {
if (nCount <= 0 || nCount > m_Objects.size() - i)
return;
- 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);
+ auto it = m_Objects.begin() + i;
+ m_Objects.erase(it, it + nCount);
}
void CPDF_Array::ConvertToIndirectObjectAt(size_t i,
@@ -151,12 +149,11 @@ void CPDF_Array::ConvertToIndirectObjectAt(size_t i,
if (i >= m_Objects.size())
return;
- CPDF_Object* pObj = m_Objects[i];
- if (!pObj || pObj->IsReference())
+ if (!m_Objects[i] || m_Objects[i]->IsReference())
return;
- uint32_t dwObjNum = pHolder->AddIndirectObject(pObj);
- m_Objects[i] = new CPDF_Reference(pHolder, dwObjNum);
+ uint32_t dwObjNum = pHolder->AddIndirectObject(m_Objects[i].release());
+ m_Objects[i] = UniqueObject(new CPDF_Reference(pHolder, dwObjNum));
}
void CPDF_Array::SetAt(size_t i, CPDF_Object* pObj) {
@@ -166,10 +163,7 @@ void CPDF_Array::SetAt(size_t i, CPDF_Object* pObj) {
ASSERT(false);
return;
}
- if (CPDF_Object* pOld = m_Objects[i])
- pOld->Release();
-
- m_Objects[i] = pObj;
+ m_Objects[i] = UniqueObject(pObj);
}
void CPDF_Array::InsertAt(size_t index, CPDF_Object* pObj) {
@@ -177,18 +171,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, nullptr);
- m_Objects[index] = pObj;
+ m_Objects.resize(index + 1);
+ m_Objects[index] = UniqueObject(pObj);
} else {
// Directly insert.
- m_Objects.insert(m_Objects.begin() + index, pObj);
+ m_Objects.insert(m_Objects.begin() + index, UniqueObject(pObj));
}
}
void CPDF_Array::Add(CPDF_Object* pObj) {
ASSERT(IsArray());
CHECK(!pObj || pObj->IsInline());
- m_Objects.push_back(pObj);
+ m_Objects.push_back(UniqueObject(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 8cfa0333bb..f473e26800 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<CPDF_Object*>::iterator;
- using const_iterator = std::vector<CPDF_Object*>::const_iterator;
+ using iterator = std::vector<UniqueObject>::iterator;
+ using const_iterator = std::vector<UniqueObject>::const_iterator;
CPDF_Array();
@@ -67,8 +67,9 @@ class CPDF_Array : public CPDF_Object {
bool bDirect,
std::set<const CPDF_Object*>* pVisited) const override;
- std::vector<CPDF_Object*> m_Objects;
+ std::vector<UniqueObject> m_Objects;
};
+
using UniqueArray = std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Object>>;
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 e23aa8ecfb..980c94d325 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;
+ CPDF_Object* value = it.second.get();
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 (CPDF_Object* pArrayObj : *pArray) {
- if (CPDF_Reference* pRef = ToReference(pArrayObj))
+ for (auto& pArrayObj : *pArray) {
+ if (CPDF_Reference* pRef = ToReference(pArrayObj.get()))
UnavailObjList.Add(pRef->GetRefObjNum());
}
}
@@ -742,7 +742,7 @@ FX_BOOL CPDF_DataAvail::CheckHintTables(DownloadHints* pHints) {
return FALSE;
}
- for (const CPDF_Object* pArrayObject : *pHintStreamRange) {
+ for (const auto& 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 aab7422b3c..435eee7248 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.
+ // in case of cyclic references, then break cycles.
m_ObjNum = kInvalidObjNum;
- for (const auto& it : m_Map) {
- if (it.second && it.second->GetObjNum() != kInvalidObjNum)
- it.second->Release();
+ for (auto& it : m_Map) {
+ if (it.second && it.second->GetObjNum() == kInvalidObjNum)
+ it.second.release();
}
}
@@ -65,20 +65,19 @@ CPDF_Object* CPDF_Dictionary::CloneNonCyclic(
bool bDirect,
std::set<const CPDF_Object*>* pVisited) const {
pVisited->insert(this);
- CPDF_Dictionary* pCopy = new CPDF_Dictionary(m_pPool);
+ UniqueDictionary pCopy = UniqueDictionary(new CPDF_Dictionary(m_pPool));
for (const auto& it : *this) {
- CPDF_Object* value = it.second;
- if (!pdfium::ContainsKey(*pVisited, value)) {
- pCopy->m_Map.insert(
- std::make_pair(it.first, value->CloneNonCyclic(bDirect, pVisited)));
+ if (!pdfium::ContainsKey(*pVisited, it.second.get())) {
+ pCopy->m_Map[it.first] =
+ UniqueObject(it.second->CloneNonCyclic(bDirect, pVisited));
}
}
- return pCopy;
+ return pCopy.release();
}
CPDF_Object* CPDF_Dictionary::GetObjectFor(const CFX_ByteString& key) const {
auto it = m_Map.find(key);
- return it != m_Map.end() ? it->second : nullptr;
+ return it != m_Map.end() ? it->second.get() : nullptr;
}
CPDF_Object* CPDF_Dictionary::GetDirectObjectFor(
@@ -174,22 +173,12 @@ bool CPDF_Dictionary::IsSignatureDict() const {
}
void CPDF_Dictionary::SetFor(const CFX_ByteString& key, CPDF_Object* pObj) {
- 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));
+ if (!pObj) {
+ m_Map.erase(key);
return;
}
-
- if (it->second == pObj)
- return;
- it->second->Release();
-
- if (pObj)
- it->second = pObj;
- else
- m_Map.erase(it);
+ ASSERT(pObj->IsInline());
+ m_Map[key] = UniqueObject(pObj);
}
void CPDF_Dictionary::ConvertToIndirectObjectFor(
@@ -199,35 +188,24 @@ void CPDF_Dictionary::ConvertToIndirectObjectFor(
if (it == m_Map.end() || it->second->IsReference())
return;
- uint32_t objnum = pHolder->AddIndirectObject(it->second);
- it->second = new CPDF_Reference(pHolder, objnum);
+ uint32_t objnum = pHolder->AddIndirectObject(it->second.release());
+ it->second = UniqueReference(new CPDF_Reference(pHolder, objnum));
}
void CPDF_Dictionary::RemoveFor(const CFX_ByteString& key) {
- auto it = m_Map.find(key);
- if (it == m_Map.end())
- return;
-
- it->second->Release();
- m_Map.erase(it);
+ m_Map.erase(key);
}
void CPDF_Dictionary::ReplaceKey(const CFX_ByteString& oldkey,
const CFX_ByteString& newkey) {
- auto old_it = m_Map.find(oldkey);
- if (old_it == m_Map.end())
+ if (oldkey == newkey)
return;
- auto new_it = m_Map.find(newkey);
- if (new_it == old_it)
+ auto old_it = m_Map.find(oldkey);
+ if (old_it == m_Map.end())
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[newkey] = std::move(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 fb8200f78c..6265522997 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<CFX_ByteString, CPDF_Object*>::iterator;
- using const_iterator = std::map<CFX_ByteString, CPDF_Object*>::const_iterator;
+ using iterator = std::map<CFX_ByteString, UniqueObject>::iterator;
+ using const_iterator = std::map<CFX_ByteString, UniqueObject>::const_iterator;
CPDF_Dictionary();
explicit CPDF_Dictionary(const CFX_WeakPtr<CFX_ByteStringPool>& pPool);
@@ -96,7 +96,7 @@ class CPDF_Dictionary : public CPDF_Object {
std::set<const CPDF_Object*>* visited) const override;
CFX_WeakPtr<CFX_ByteStringPool> m_pPool;
- std::map<CFX_ByteString, CPDF_Object*> m_Map;
+ std::map<CFX_ByteString, UniqueObject> m_Map;
};
using UniqueDictionary =
diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp
index 8215226ef3..e5a5f54915 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, dict2->GetObjectFor(it->first)))
+ if (!Equal(it->second.get(), 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 c29ae18da2..40a615fa47 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;
+ CPDF_Object* pElement = it->second.get();
++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 5221832f80..e9416aecad 100644
--- a/core/fpdfapi/parser/cpdf_reference.h
+++ b/core/fpdfapi/parser/cpdf_reference.h
@@ -47,6 +47,9 @@ class CPDF_Reference : public CPDF_Object {
uint32_t m_RefObjNum;
};
+using UniqueReference =
+ std::unique_ptr<CPDF_Reference, ReleaseDeleter<CPDF_Object>>;
+
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 756eccfba1..b440f94354 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<const CPDF_Object*>* pVisited) const override;
- std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>> m_pDict;
+ UniqueDictionary m_pDict;
bool m_bMemoryBased = true;
uint32_t m_dwSize = 0;
std::unique_ptr<uint8_t, FxFreeDeleter> m_pDataBuf;
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp
index 7b9ead4005..6f1ce14d6e 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;
+ CPDF_Object* pValue = it.second.get();
buf << "/" << PDF_NameEncode(key);
if (pValue && !pValue->IsInline()) {
buf << " " << pValue->GetObjNum() << " 0 R ";