Avoid ambiguity in CPDF_{Dictionary,Array}Locker constructors

Provide a special case for non-const retained objects, so that the
compiler doesn't have to choose between down-converting to raw ptr
vs. constructing an equivalent const retained object.

-- remove now needless calls to Get()

Change-Id: I684c0637c91a3cae3c990a884df79ccde4c2a38f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98410
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp
index 641afff..ab1dfeb 100644
--- a/core/fpdfapi/edit/cpdf_creator.cpp
+++ b/core/fpdfapi/edit/cpdf_creator.cpp
@@ -426,8 +426,7 @@
   }
 
   if (m_pParser) {
-    RetainPtr<CPDF_Dictionary> p = m_pParser->GetCombinedTrailer();
-    CPDF_DictionaryLocker locker(p.Get());
+    CPDF_DictionaryLocker locker(m_pParser->GetCombinedTrailer());
     for (const auto& it : locker) {
       const ByteString& key = it.first;
       CPDF_Object* pValue = it.second.Get();
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index 244e884..850d701 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -278,6 +278,11 @@
   m_pArray->m_LockCount++;
 }
 
+CPDF_ArrayLocker::CPDF_ArrayLocker(RetainPtr<CPDF_Array> pArray)
+    : m_pArray(std::move(pArray)) {
+  m_pArray->m_LockCount++;
+}
+
 CPDF_ArrayLocker::CPDF_ArrayLocker(RetainPtr<const CPDF_Array> pArray)
     : m_pArray(std::move(pArray)) {
   m_pArray->m_LockCount++;
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index bcf04e2..bbbd30a 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -166,6 +166,7 @@
   using const_iterator = CPDF_Array::const_iterator;
 
   explicit CPDF_ArrayLocker(const CPDF_Array* pArray);
+  explicit CPDF_ArrayLocker(RetainPtr<CPDF_Array> pArray);
   explicit CPDF_ArrayLocker(RetainPtr<const CPDF_Array> pArray);
   ~CPDF_ArrayLocker();
 
diff --git a/core/fpdfapi/parser/cpdf_array_unittest.cpp b/core/fpdfapi/parser/cpdf_array_unittest.cpp
index 82ca9db..408e8f1 100644
--- a/core/fpdfapi/parser/cpdf_array_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_array_unittest.cpp
@@ -230,9 +230,9 @@
   auto arr = pdfium::MakeRetain<CPDF_Array>();
   for (size_t i = 0; i < std::size(elems); ++i)
     arr->InsertNewAt<CPDF_Number>(i, elems[i]);
-  size_t index = 0;
 
-  CPDF_ArrayLocker locker(arr.Get());
+  size_t index = 0;
+  CPDF_ArrayLocker locker(arr);
   for (const auto& it : locker)
     EXPECT_EQ(elems[index++], it->AsNumber()->GetInteger());
   EXPECT_EQ(std::size(elems), index);
diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp
index 84f0d79..ea03f5b 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary.cpp
@@ -380,6 +380,12 @@
 }
 
 CPDF_DictionaryLocker::CPDF_DictionaryLocker(
+    RetainPtr<CPDF_Dictionary> pDictionary)
+    : m_pDictionary(std::move(pDictionary)) {
+  m_pDictionary->m_LockCount++;
+}
+
+CPDF_DictionaryLocker::CPDF_DictionaryLocker(
     RetainPtr<const CPDF_Dictionary> pDictionary)
     : m_pDictionary(std::move(pDictionary)) {
   m_pDictionary->m_LockCount++;
diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h
index b7b6c1d..a28cbc3 100644
--- a/core/fpdfapi/parser/cpdf_dictionary.h
+++ b/core/fpdfapi/parser/cpdf_dictionary.h
@@ -154,6 +154,7 @@
   using const_iterator = CPDF_Dictionary::const_iterator;
 
   explicit CPDF_DictionaryLocker(const CPDF_Dictionary* pDictionary);
+  explicit CPDF_DictionaryLocker(RetainPtr<CPDF_Dictionary> pDictionary);
   explicit CPDF_DictionaryLocker(RetainPtr<const CPDF_Dictionary> pDictionary);
   ~CPDF_DictionaryLocker();
 
diff --git a/core/fpdfapi/parser/cpdf_dictionary_unittest.cpp b/core/fpdfapi/parser/cpdf_dictionary_unittest.cpp
index 73bd8c4..574b560 100644
--- a/core/fpdfapi/parser/cpdf_dictionary_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_dictionary_unittest.cpp
@@ -18,7 +18,7 @@
   dict->SetNewFor<CPDF_Stream>("the-stream");
   dict->SetNewFor<CPDF_Number>("the-number", 42);
 
-  CPDF_DictionaryLocker locked_dict(dict.Get());
+  CPDF_DictionaryLocker locked_dict(dict);
   auto it = locked_dict.begin();
   EXPECT_NE(it, locked_dict.end());
   EXPECT_EQ(it->first, ByteString("the-array"));
diff --git a/fpdfsdk/fpdf_flatten.cpp b/fpdfsdk/fpdf_flatten.cpp
index 202ec82..aa99541 100644
--- a/fpdfsdk/fpdf_flatten.cpp
+++ b/fpdfsdk/fpdf_flatten.cpp
@@ -354,7 +354,7 @@
         pAPStream = pAPDict->GetMutableStreamFor(sAnnotState);
       } else {
         if (pAPDict->size() > 0) {
-          CPDF_DictionaryLocker locker(pAPDict.Get());
+          CPDF_DictionaryLocker locker(pAPDict);
           RetainPtr<CPDF_Object> pFirstObj = locker.begin()->second;
           if (pFirstObj) {
             if (pFirstObj->IsReference())
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp
index 946fa95..4195257 100644
--- a/fxjs/cjs_document.cpp
+++ b/fxjs/cjs_document.cpp
@@ -696,8 +696,7 @@
                               pRuntime->NewString(cwTrapped.AsStringView()));
 
   // PutObjectProperty() calls below may re-enter JS and change info dict.
-  auto pCopy = pDictionary->Clone();
-  CPDF_DictionaryLocker locker(ToDictionary(pCopy.Get()));
+  CPDF_DictionaryLocker locker(ToDictionary(pDictionary->Clone()));
   for (const auto& it : locker) {
     const ByteString& bsKey = it.first;
     CPDF_Object* pValueObj = it.second.Get();