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.h | |
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.h')
-rw-r--r-- | core/fpdfapi/parser/cpdf_dictionary.h | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h index 2e972d0577..e6abd26cc2 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.h +++ b/core/fpdfapi/parser/cpdf_dictionary.h @@ -11,12 +11,14 @@ #include <memory> #include <set> #include <utility> +#include <vector> #include "core/fpdfapi/parser/cpdf_object.h" #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/string_pool_template.h" #include "core/fxcrt/weak_ptr.h" +#include "third_party/base/logging.h" #include "third_party/base/ptr_util.h" class CPDF_IndirectObjectHolder; @@ -41,6 +43,8 @@ class CPDF_Dictionary final : public CPDF_Object { bool WriteTo(IFX_ArchiveStream* archive, const CPDF_Encryptor* encryptor) const override; + bool IsLocked() const { return !!m_LockCount; } + size_t size() const { return m_Map.size(); } const CPDF_Object* GetObjectFor(const ByteString& key) const; CPDF_Object* GetObjectFor(const ByteString& key); @@ -65,6 +69,7 @@ class CPDF_Dictionary final : public CPDF_Object { float GetFloatFor(const ByteString& key) const { return GetNumberFor(key); } bool KeyExist(const ByteString& key) const; + std::vector<ByteString> GetKeys() const; // Set* functions invalidate iterators for the element with the key |key|. // Takes ownership of |pObj|, returns an unowned pointer to it. @@ -76,6 +81,7 @@ class CPDF_Dictionary final : public CPDF_Object { typename std::enable_if<!CanInternStrings<T>::value, T*>::type SetNewFor( const ByteString& key, Args&&... args) { + CHECK(!IsLocked()); return static_cast<T*>( SetFor(key, pdfium::MakeUnique<T>(std::forward<Args>(args)...))); } @@ -83,6 +89,7 @@ class CPDF_Dictionary final : public CPDF_Object { typename std::enable_if<CanInternStrings<T>::value, T*>::type SetNewFor( const ByteString& key, Args&&... args) { + CHECK(!IsLocked()); return static_cast<T*>(SetFor( key, pdfium::MakeUnique<T>(m_pPool, std::forward<Args>(args)...))); } @@ -100,21 +107,41 @@ class CPDF_Dictionary final : public CPDF_Object { // Invalidates iterators for the element with the key |oldkey|. void ReplaceKey(const ByteString& oldkey, const ByteString& newkey); - const_iterator begin() const { return m_Map.begin(); } - const_iterator end() const { return m_Map.end(); } - WeakPtr<ByteStringPool> GetByteStringPool() const { return m_pPool; } private: + friend class CPDF_DictionaryLocker; + ByteString MaybeIntern(const ByteString& str); std::unique_ptr<CPDF_Object> CloneNonCyclic( bool bDirect, std::set<const CPDF_Object*>* visited) const override; + mutable uint32_t m_LockCount = 0; WeakPtr<ByteStringPool> m_pPool; std::map<ByteString, std::unique_ptr<CPDF_Object>> m_Map; }; +class CPDF_DictionaryLocker { + public: + using const_iterator = CPDF_Dictionary::const_iterator; + + explicit CPDF_DictionaryLocker(const CPDF_Dictionary* pDictionary); + ~CPDF_DictionaryLocker(); + + const_iterator begin() const { + CHECK(m_pDictionary->IsLocked()); + return m_pDictionary->m_Map.begin(); + } + const_iterator end() const { + CHECK(m_pDictionary->IsLocked()); + return m_pDictionary->m_Map.end(); + } + + private: + UnownedPtr<const CPDF_Dictionary> const m_pDictionary; +}; + inline CPDF_Dictionary* ToDictionary(CPDF_Object* obj) { return obj ? obj->AsDictionary() : nullptr; } |