Add additional dictionary locker methods.
Allow returning unretained references to the full complement of
objects from locked dictionaries.
-- re-write other dictionary methods in terms of new internal ones.
-- add tests for new cases.
Change-Id: Ie44fbf17ab5a1689e39e1e593d9456b6ce505273
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/97850
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index e03d286..8d274f7 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -71,89 +71,91 @@
return pCopy;
}
-CPDF_Object* CPDF_Dictionary::GetMutableObjectForInternal(
- const ByteString& key) {
- auto it = m_Map.find(key);
- return it != m_Map.end() ? it->second.Get() : nullptr;
-}
-
const CPDF_Object* CPDF_Dictionary::GetObjectForInternal(
const ByteString& key) const {
- return const_cast<CPDF_Dictionary*>(this)->GetMutableObjectForInternal(key);
-}
-
-RetainPtr<CPDF_Object> CPDF_Dictionary::GetMutableObjectFor(
- const ByteString& key) {
- return pdfium::WrapRetain(GetMutableObjectForInternal(key));
+ auto it = m_Map.find(key);
+ return it != m_Map.end() ? it->second.Get() : nullptr;
}
const CPDF_Object* CPDF_Dictionary::GetObjectFor(const ByteString& key) const {
return GetObjectForInternal(key);
}
+RetainPtr<CPDF_Object> CPDF_Dictionary::GetMutableObjectFor(
+ const ByteString& key) {
+ return pdfium::WrapRetain(
+ const_cast<CPDF_Object*>(GetObjectForInternal(key)));
+}
+
+const CPDF_Object* CPDF_Dictionary::GetDirectObjectForInternal(
+ const ByteString& key) const {
+ const CPDF_Object* p = GetObjectForInternal(key);
+ return p ? const_cast<CPDF_Object*>(p)->GetMutableDirect().Get() : nullptr;
+}
+
RetainPtr<const CPDF_Object> CPDF_Dictionary::GetDirectObjectFor(
const ByteString& key) const {
- return const_cast<CPDF_Dictionary*>(this)->GetMutableDirectObjectFor(key);
+ return pdfium::WrapRetain(GetDirectObjectForInternal(key));
}
RetainPtr<CPDF_Object> CPDF_Dictionary::GetMutableDirectObjectFor(
const ByteString& key) {
- RetainPtr<CPDF_Object> p = GetMutableObjectFor(key);
- return p ? p->GetMutableDirect() : nullptr;
+ return pdfium::WrapRetain(
+ const_cast<CPDF_Object*>(GetDirectObjectForInternal(key)));
}
ByteString CPDF_Dictionary::GetStringFor(const ByteString& key) const {
- const CPDF_Object* p = GetObjectFor(key);
+ const CPDF_Object* p = GetObjectForInternal(key);
return p ? p->GetString() : ByteString();
}
ByteString CPDF_Dictionary::GetStringFor(const ByteString& key,
const ByteString& def) const {
- const CPDF_Object* p = GetObjectFor(key);
+ const CPDF_Object* p = GetObjectForInternal(key);
return p ? p->GetString() : ByteString(def);
}
WideString CPDF_Dictionary::GetUnicodeTextFor(const ByteString& key) const {
- const CPDF_Object* p = GetObjectFor(key);
+ const CPDF_Object* p = GetObjectForInternal(key);
if (const CPDF_Reference* pRef = ToReference(p))
p = pRef->GetDirect().Get();
return p ? p->GetUnicodeText() : WideString();
}
ByteString CPDF_Dictionary::GetNameFor(const ByteString& key) const {
- const CPDF_Name* p = ToName(GetObjectFor(key));
+ const CPDF_Name* p = ToName(GetObjectForInternal(key));
return p ? p->GetString() : ByteString();
}
bool CPDF_Dictionary::GetBooleanFor(const ByteString& key,
bool bDefault) const {
- const CPDF_Object* p = GetObjectFor(key);
+ const CPDF_Object* p = GetObjectForInternal(key);
return ToBoolean(p) ? p->GetInteger() != 0 : bDefault;
}
int CPDF_Dictionary::GetIntegerFor(const ByteString& key) const {
- const CPDF_Object* p = GetObjectFor(key);
+ const CPDF_Object* p = GetObjectForInternal(key);
return p ? p->GetInteger() : 0;
}
int CPDF_Dictionary::GetIntegerFor(const ByteString& key, int def) const {
- const CPDF_Object* p = GetObjectFor(key);
+ const CPDF_Object* p = GetObjectForInternal(key);
return p ? p->GetInteger() : def;
}
int CPDF_Dictionary::GetDirectIntegerFor(const ByteString& key) const {
- const CPDF_Number* p = ToNumber(GetObjectFor(key));
+ const CPDF_Number* p = ToNumber(GetObjectForInternal(key));
return p ? p->GetInteger() : 0;
}
float CPDF_Dictionary::GetFloatFor(const ByteString& key) const {
- const CPDF_Object* p = GetObjectFor(key);
+ const CPDF_Object* p = GetObjectForInternal(key);
return p ? p->GetNumber() : 0;
}
-const CPDF_Dictionary* CPDF_Dictionary::GetDictFor(
+const CPDF_Dictionary* CPDF_Dictionary::GetDictForInternal(
const ByteString& key) const {
- RetainPtr<const CPDF_Object> p = GetDirectObjectFor(key);
+ const CPDF_Object* p = GetDirectObjectForInternal(key);
if (!p)
return nullptr;
if (const CPDF_Dictionary* pDict = p->AsDictionary())
@@ -163,9 +165,15 @@
return nullptr;
}
+const CPDF_Dictionary* CPDF_Dictionary::GetDictFor(
+ const ByteString& key) const {
+ return GetDictForInternal(key);
+}
+
RetainPtr<CPDF_Dictionary> CPDF_Dictionary::GetMutableDictFor(
const ByteString& key) {
- return pdfium::WrapRetain(const_cast<CPDF_Dictionary*>(GetDictFor(key)));
+ return pdfium::WrapRetain(
+ const_cast<CPDF_Dictionary*>(GetDictForInternal(key)));
}
RetainPtr<CPDF_Dictionary> CPDF_Dictionary::GetOrCreateDictFor(
@@ -176,13 +184,18 @@
return pdfium::WrapRetain(SetNewFor<CPDF_Dictionary>(key));
}
+const CPDF_Array* CPDF_Dictionary::GetArrayForInternal(
+ const ByteString& key) const {
+ return ToArray(GetDirectObjectForInternal(key));
+}
+
const CPDF_Array* CPDF_Dictionary::GetArrayFor(const ByteString& key) const {
- return ToArray(GetDirectObjectFor(key).Get());
+ return GetArrayForInternal(key);
}
RetainPtr<CPDF_Array> CPDF_Dictionary::GetMutableArrayFor(
const ByteString& key) {
- return pdfium::WrapRetain(const_cast<CPDF_Array*>(GetArrayFor(key)));
+ return pdfium::WrapRetain(const_cast<CPDF_Array*>(GetArrayForInternal(key)));
}
RetainPtr<CPDF_Array> CPDF_Dictionary::GetOrCreateArrayFor(
@@ -193,19 +206,30 @@
return pdfium::WrapRetain(SetNewFor<CPDF_Array>(key));
}
+const CPDF_Stream* CPDF_Dictionary::GetStreamForInternal(
+ const ByteString& key) const {
+ return ToStream(GetDirectObjectForInternal(key));
+}
+
RetainPtr<const CPDF_Stream> CPDF_Dictionary::GetStreamFor(
const ByteString& key) const {
- return ToStream(GetDirectObjectFor(key));
+ return pdfium::WrapRetain(GetStreamForInternal(key));
}
RetainPtr<CPDF_Stream> CPDF_Dictionary::GetMutableStreamFor(
const ByteString& key) {
- return ToStream(GetMutableDirectObjectFor(key));
+ return pdfium::WrapRetain(
+ const_cast<CPDF_Stream*>(GetStreamForInternal(key)));
+}
+
+const CPDF_Number* CPDF_Dictionary::GetNumberForInternal(
+ const ByteString& key) const {
+ return ToNumber(GetObjectForInternal(key));
}
RetainPtr<const CPDF_Number> CPDF_Dictionary::GetNumberFor(
const ByteString& key) const {
- return pdfium::WrapRetain(ToNumber(GetObjectFor(key)));
+ return pdfium::WrapRetain(GetNumberForInternal(key));
}
CFX_FloatRect CPDF_Dictionary::GetRectFor(const ByteString& key) const {
@@ -349,13 +373,3 @@
CPDF_DictionaryLocker::~CPDF_DictionaryLocker() {
m_pDictionary->m_LockCount--;
}
-
-const CPDF_Array* CPDF_DictionaryLocker::GetArrayFor(
- const ByteString& key) const {
- return ToArray(GetObjectFor(key));
-}
-
-const CPDF_Dictionary* CPDF_DictionaryLocker::GetDictFor(
- const ByteString& key) const {
- return ToDictionary(GetObjectFor(key));
-}
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index a712096..9cb6bb6 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -130,7 +130,11 @@
// No guarantees about result lifetime, use with caution.
const CPDF_Object* GetObjectForInternal(const ByteString& key) const;
- CPDF_Object* GetMutableObjectForInternal(const ByteString& key);
+ const CPDF_Object* GetDirectObjectForInternal(const ByteString& key) const;
+ const CPDF_Array* GetArrayForInternal(const ByteString& key) const;
+ const CPDF_Dictionary* GetDictForInternal(const ByteString& key) const;
+ const CPDF_Number* GetNumberForInternal(const ByteString& key) const;
+ const CPDF_Stream* GetStreamForInternal(const ByteString& key) const;
ByteString MaybeIntern(const ByteString& str);
RetainPtr<CPDF_Object> CloneNonCyclic(
@@ -162,12 +166,30 @@
// Results are only valid for the lifetime of the Dictionary Locker.
const CPDF_Dictionary* GetUnderlying() const { return m_pDictionary.Get(); }
- const CPDF_Array* GetArrayFor(const ByteString& key) const;
- const CPDF_Dictionary* GetDictFor(const ByteString& key) const;
const CPDF_Object* GetObjectFor(const ByteString& key) const {
CHECK(m_pDictionary->IsLocked());
return m_pDictionary->GetObjectForInternal(key);
}
+ const CPDF_Object* GetDirectObjectFor(const ByteString& key) const {
+ CHECK(m_pDictionary->IsLocked());
+ return m_pDictionary->GetDirectObjectForInternal(key);
+ }
+ const CPDF_Array* GetArrayFor(const ByteString& key) const {
+ CHECK(m_pDictionary->IsLocked());
+ return m_pDictionary->GetArrayForInternal(key);
+ }
+ const CPDF_Dictionary* GetDictFor(const ByteString& key) const {
+ CHECK(m_pDictionary->IsLocked());
+ return m_pDictionary->GetDictForInternal(key);
+ }
+ const CPDF_Number* GetNumberFor(const ByteString& key) const {
+ CHECK(m_pDictionary->IsLocked());
+ return m_pDictionary->GetNumberForInternal(key);
+ }
+ const CPDF_Stream* GetStreamFor(const ByteString& key) const {
+ CHECK(m_pDictionary->IsLocked());
+ return m_pDictionary->GetStreamForInternal(key);
+ }
private:
RetainPtr<const CPDF_Dictionary> const m_pDictionary;
diff --git a/core/fpdfapi/parser/cpdf_dictionary_unittest.cpp b/core/fpdfapi/parser/cpdf_dictionary_unittest.cpp
index dab1a61..462d5a0 100644
--- a/core/fpdfapi/parser/cpdf_dictionary_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary_unittest.cpp
@@ -7,18 +7,45 @@
#include <utility>
#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(DictionaryTest, LockerGetters) {
auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
- dict->SetNewFor<CPDF_Dictionary>("A");
- dict->SetNewFor<CPDF_Array>("B");
+ dict->SetNewFor<CPDF_Dictionary>("the-dictionary");
+ dict->SetNewFor<CPDF_Array>("the-array");
+ dict->SetNewFor<CPDF_Stream>("the-stream");
+ dict->SetNewFor<CPDF_Number>("the-number", 42);
CPDF_DictionaryLocker locked_dict(std::move(dict));
- EXPECT_TRUE(locked_dict.GetObjectFor("A"));
- EXPECT_FALSE(locked_dict.GetArrayFor("A"));
- EXPECT_TRUE(locked_dict.GetDictFor("A"));
- EXPECT_TRUE(locked_dict.GetObjectFor("B"));
- EXPECT_TRUE(locked_dict.GetArrayFor("B"));
- EXPECT_FALSE(locked_dict.GetDictFor("B"));
+ EXPECT_TRUE(locked_dict.GetObjectFor("the-dictionary"));
+ EXPECT_FALSE(locked_dict.GetArrayFor("the-dictionary"));
+ EXPECT_TRUE(locked_dict.GetDictFor("the-dictionary"));
+ EXPECT_FALSE(locked_dict.GetStreamFor("the-dictionary"));
+ EXPECT_FALSE(locked_dict.GetNumberFor("the-dictionary"));
+
+ EXPECT_TRUE(locked_dict.GetObjectFor("the-array"));
+ EXPECT_TRUE(locked_dict.GetArrayFor("the-array"));
+ EXPECT_FALSE(locked_dict.GetDictFor("the-array"));
+ EXPECT_FALSE(locked_dict.GetStreamFor("the-array"));
+ EXPECT_FALSE(locked_dict.GetNumberFor("the-array"));
+
+ EXPECT_TRUE(locked_dict.GetObjectFor("the-stream"));
+ EXPECT_FALSE(locked_dict.GetArrayFor("the-stream"));
+ EXPECT_FALSE(locked_dict.GetDictFor("the-stream"));
+ EXPECT_TRUE(locked_dict.GetStreamFor("the-stream"));
+ EXPECT_FALSE(locked_dict.GetNumberFor("the-stream"));
+
+ EXPECT_TRUE(locked_dict.GetObjectFor("the-number"));
+ EXPECT_FALSE(locked_dict.GetArrayFor("the-number"));
+ EXPECT_FALSE(locked_dict.GetDictFor("the-number"));
+ EXPECT_FALSE(locked_dict.GetStreamFor("the-number"));
+ EXPECT_TRUE(locked_dict.GetNumberFor("the-number"));
+
+ EXPECT_FALSE(locked_dict.GetObjectFor("nonesuch"));
+ EXPECT_FALSE(locked_dict.GetArrayFor("nonesuch"));
+ EXPECT_FALSE(locked_dict.GetDictFor("nonesuch"));
+ EXPECT_FALSE(locked_dict.GetStreamFor("nonesuch"));
+ EXPECT_FALSE(locked_dict.GetNumberFor("nonesuch"));
}