diff options
author | Tom Sepez <tsepez@chromium.org> | 2018-10-17 17:57:51 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-10-17 17:57:51 +0000 |
commit | 5ae6c564d16ce8b625df3d1950abc822f9ecc987 (patch) | |
tree | 96bb64df3166e46db397e405789588bf8dc53842 /core/fpdfapi/parser/cpdf_dictionary.cpp | |
parent | 785a26dc649af80c593f899a606dff4dae7c48fd (diff) | |
download | pdfium-5ae6c564d16ce8b625df3d1950abc822f9ecc987.tar.xz |
Add CPDF_{Array,Dictionary}Locker to catch illegal iteration patterns.
Move begin/end methods onto locker object which tracks whether
iterators are in existence.
Change-Id: Ia869f313fce48d10a0d0180d0cc083eed6ea1584
Reviewed-on: https://pdfium-review.googlesource.com/c/44070
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'core/fpdfapi/parser/cpdf_dictionary.cpp')
-rw-r--r-- | core/fpdfapi/parser/cpdf_dictionary.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp index 9c06e42804..6c005c8db2 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.cpp +++ b/core/fpdfapi/parser/cpdf_dictionary.cpp @@ -72,7 +72,8 @@ std::unique_ptr<CPDF_Object> CPDF_Dictionary::CloneNonCyclic( std::set<const CPDF_Object*>* pVisited) const { pVisited->insert(this); auto pCopy = pdfium::MakeUnique<CPDF_Dictionary>(m_pPool); - for (const auto& it : *this) { + CPDF_DictionaryLocker locker(this); + for (const auto& it : locker) { if (!pdfium::ContainsKey(*pVisited, it.second.get())) { std::set<const CPDF_Object*> visited(*pVisited); if (auto obj = it.second->CloneNonCyclic(bDirect, &visited)) @@ -195,8 +196,17 @@ bool CPDF_Dictionary::KeyExist(const ByteString& key) const { return pdfium::ContainsKey(m_Map, key); } +std::vector<ByteString> CPDF_Dictionary::GetKeys() const { + std::vector<ByteString> result; + CPDF_DictionaryLocker locker(this); + for (const auto& item : locker) + result.push_back(item.first); + return result; +} + CPDF_Object* CPDF_Dictionary::SetFor(const ByteString& key, std::unique_ptr<CPDF_Object> pObj) { + CHECK(!IsLocked()); if (!pObj) { m_Map.erase(key); return nullptr; @@ -210,6 +220,7 @@ CPDF_Object* CPDF_Dictionary::SetFor(const ByteString& key, void CPDF_Dictionary::ConvertToIndirectObjectFor( const ByteString& key, CPDF_IndirectObjectHolder* pHolder) { + CHECK(!IsLocked()); auto it = m_Map.find(key); if (it == m_Map.end() || it->second->IsReference()) return; @@ -219,6 +230,7 @@ void CPDF_Dictionary::ConvertToIndirectObjectFor( } std::unique_ptr<CPDF_Object> CPDF_Dictionary::RemoveFor(const ByteString& key) { + CHECK(!IsLocked()); std::unique_ptr<CPDF_Object> result; auto it = m_Map.find(key); if (it != m_Map.end()) { @@ -230,6 +242,7 @@ std::unique_ptr<CPDF_Object> CPDF_Dictionary::RemoveFor(const ByteString& key) { void CPDF_Dictionary::ReplaceKey(const ByteString& oldkey, const ByteString& newkey) { + CHECK(!IsLocked()); auto old_it = m_Map.find(oldkey); if (old_it == m_Map.end()) return; @@ -273,7 +286,8 @@ bool CPDF_Dictionary::WriteTo(IFX_ArchiveStream* archive, const bool is_signature = CPDF_CryptoHandler::IsSignatureDictionary(this); - for (const auto& it : *this) { + CPDF_DictionaryLocker locker(this); + for (const auto& it : locker) { const ByteString& key = it.first; CPDF_Object* pValue = it.second.get(); if (!archive->WriteString("/") || @@ -288,3 +302,12 @@ bool CPDF_Dictionary::WriteTo(IFX_ArchiveStream* archive, } return archive->WriteString(">>"); } + +CPDF_DictionaryLocker::CPDF_DictionaryLocker(const CPDF_Dictionary* pDictionary) + : m_pDictionary(pDictionary) { + m_pDictionary->m_LockCount++; +} + +CPDF_DictionaryLocker::~CPDF_DictionaryLocker() { + m_pDictionary->m_LockCount--; +} |