Use retained locals in CPDF_FormField

Fixes one of the last places where unretained references remained.

Change-Id: I2b76038ca81a48643ef3eb5789c6695047ade785
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/100681
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index bd6601c..705827d 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -33,9 +33,10 @@
 
 namespace {
 
-const CPDF_Object* GetFieldAttrRecursive(const CPDF_Dictionary* pFieldDict,
-                                         const ByteString& name,
-                                         int nLevel) {
+RetainPtr<const CPDF_Object> GetFieldAttrRecursive(
+    const CPDF_Dictionary* pFieldDict,
+    const ByteString& name,
+    int nLevel) {
   static constexpr int kGetFieldMaxRecursion = 32;
   if (!pFieldDict || nLevel > kGetFieldMaxRecursion)
     return nullptr;
@@ -49,12 +50,6 @@
       nLevel + 1);
 }
 
-const CPDF_Object* GetFieldAttrForDictInternal(
-    const CPDF_Dictionary* pFieldDict,
-    const ByteString& name) {
-  return GetFieldAttrRecursive(pFieldDict, name, 0);
-}
-
 }  // namespace
 
 // static
@@ -70,15 +65,15 @@
 RetainPtr<const CPDF_Object> CPDF_FormField::GetFieldAttrForDict(
     const CPDF_Dictionary* pFieldDict,
     const ByteString& name) {
-  return pdfium::WrapRetain(GetFieldAttrForDictInternal(pFieldDict, name));
+  return GetFieldAttrRecursive(pFieldDict, name, 0);
 }
 
 // static
 RetainPtr<CPDF_Object> CPDF_FormField::GetMutableFieldAttrForDict(
     CPDF_Dictionary* pFieldDict,
     const ByteString& name) {
-  return pdfium::WrapRetain(
-      const_cast<CPDF_Object*>(GetFieldAttrForDictInternal(pFieldDict, name)));
+  return pdfium::WrapRetain(const_cast<CPDF_Object*>(
+      GetFieldAttrRecursive(pFieldDict, name, 0).Get()));
 }
 
 // static
@@ -112,7 +107,8 @@
 CPDF_FormField::~CPDF_FormField() = default;
 
 void CPDF_FormField::InitFieldFlags() {
-  const CPDF_Object* ft_attr = GetFieldAttrInternal(pdfium::form_fields::kFT);
+  RetainPtr<const CPDF_Object> ft_attr =
+      GetFieldAttrInternal(pdfium::form_fields::kFT);
   ByteString type_name = ft_attr ? ft_attr->GetString() : ByteString();
   uint32_t flags = GetFieldFlags();
   m_bRequired = flags & pdfium::form_flags::kRequired;
@@ -154,7 +150,7 @@
 
 RetainPtr<const CPDF_Object> CPDF_FormField::GetFieldAttr(
     const ByteString& name) const {
-  return pdfium::WrapRetain(GetFieldAttrInternal(name));
+  return GetFieldAttrInternal(name);
 }
 
 RetainPtr<const CPDF_Dictionary> CPDF_FormField::GetFieldDict() const {
@@ -198,11 +194,11 @@
       {
         // Limit scope of |pDV| and |pV| because they may get invalidated
         // during notification below.
-        const CPDF_Object* pDV = GetDefaultValueObject();
+        RetainPtr<const CPDF_Object> pDV = GetDefaultValueObject();
         if (pDV)
           csDValue = pDV->GetUnicodeText();
 
-        const CPDF_Object* pV = GetValueObject();
+        RetainPtr<const CPDF_Object> pV = GetValueObject();
         if (pV)
           csValue = pV->GetUnicodeText();
       }
@@ -217,7 +213,7 @@
       {
         // Limit scope of |pDV| because it may get invalidated during
         // notification below.
-        const CPDF_Object* pDV = GetDefaultValueObject();
+        RetainPtr<const CPDF_Object> pDV = GetDefaultValueObject();
         if (pDV) {
           RetainPtr<CPDF_Object> pClone = pDV->Clone();
           if (!pClone)
@@ -283,22 +279,26 @@
 }
 
 CPDF_AAction CPDF_FormField::GetAdditionalAction() const {
-  const CPDF_Object* pObj = GetFieldAttrInternal(pdfium::form_fields::kAA);
+  RetainPtr<const CPDF_Object> pObj =
+      GetFieldAttrInternal(pdfium::form_fields::kAA);
   return CPDF_AAction(pObj ? pObj->GetDict() : nullptr);
 }
 
 WideString CPDF_FormField::GetAlternateName() const {
-  const CPDF_Object* pObj = GetFieldAttrInternal(pdfium::form_fields::kTU);
+  RetainPtr<const CPDF_Object> pObj =
+      GetFieldAttrInternal(pdfium::form_fields::kTU);
   return pObj ? pObj->GetUnicodeText() : WideString();
 }
 
 WideString CPDF_FormField::GetMappingName() const {
-  const CPDF_Object* pObj = GetFieldAttrInternal(pdfium::form_fields::kTM);
+  RetainPtr<const CPDF_Object> pObj =
+      GetFieldAttrInternal(pdfium::form_fields::kTM);
   return pObj ? pObj->GetUnicodeText() : WideString();
 }
 
 uint32_t CPDF_FormField::GetFieldFlags() const {
-  const CPDF_Object* pObj = GetFieldAttrInternal(pdfium::form_fields::kFf);
+  RetainPtr<const CPDF_Object> pObj =
+      GetFieldAttrInternal(pdfium::form_fields::kFf);
   return pObj ? pObj->GetInteger() : 0;
 }
 
@@ -311,7 +311,7 @@
   if (GetType() == kCheckBox || GetType() == kRadioButton)
     return GetCheckValue(bDefault);
 
-  const CPDF_Object* pValue =
+  RetainPtr<const CPDF_Object> pValue =
       bDefault ? GetDefaultValueObject() : GetValueObject();
   if (!pValue) {
     if (!bDefault && m_Type != kText)
@@ -324,11 +324,13 @@
     case CPDF_Object::kString:
     case CPDF_Object::kStream:
       return pValue->GetUnicodeText();
-    case CPDF_Object::kArray:
-      pValue = pValue->AsArray()->GetDirectObjectAt(0).Get();
-      if (pValue)
-        return pValue->GetUnicodeText();
+    case CPDF_Object::kArray: {
+      RetainPtr<const CPDF_Object> pNewValue =
+          pValue->AsArray()->GetDirectObjectAt(0);
+      if (pNewValue)
+        return pNewValue->GetUnicodeText();
       break;
+    }
     default:
       break;
   }
@@ -413,7 +415,7 @@
 }
 
 int CPDF_FormField::GetMaxLen() const {
-  const CPDF_Object* pObj = GetFieldAttrInternal("MaxLen");
+  RetainPtr<const CPDF_Object> pObj = GetFieldAttrInternal("MaxLen");
   if (pObj)
     return pObj->GetInteger();
 
@@ -549,7 +551,7 @@
 
 int CPDF_FormField::GetDefaultSelectedItem() const {
   DCHECK(GetType() == kComboBox || GetType() == kListBox);
-  const CPDF_Object* pValue = GetDefaultValueObject();
+  RetainPtr<const CPDF_Object> pValue = GetDefaultValueObject();
   if (!pValue)
     return -1;
   WideString csDV = pValue->GetUnicodeText();
@@ -563,12 +565,12 @@
 }
 
 int CPDF_FormField::CountOptions() const {
-  const CPDF_Array* pArray = ToArray(GetFieldAttrInternal("Opt"));
+  RetainPtr<const CPDF_Array> pArray = ToArray(GetFieldAttrInternal("Opt"));
   return pArray ? fxcrt::CollectionSize<int>(*pArray) : 0;
 }
 
 WideString CPDF_FormField::GetOptionText(int index, int sub_index) const {
-  const CPDF_Array* pArray = ToArray(GetFieldAttrInternal("Opt"));
+  RetainPtr<const CPDF_Array> pArray = ToArray(GetFieldAttrInternal("Opt"));
   if (!pArray)
     return WideString();
 
@@ -635,7 +637,7 @@
     }
   }
 
-  const CPDF_Object* pOpt = GetFieldAttrInternal("Opt");
+  RetainPtr<const CPDF_Object> pOpt = GetFieldAttrInternal("Opt");
   if (!ToArray(pOpt)) {
     ByteString csBExport = PDF_EncodeText(csWExport.AsStringView());
     if (bChecked) {
@@ -695,12 +697,12 @@
 }
 
 int CPDF_FormField::GetTopVisibleIndex() const {
-  const CPDF_Object* pObj = GetFieldAttrInternal("TI");
+  RetainPtr<const CPDF_Object> pObj = GetFieldAttrInternal("TI");
   return pObj ? pObj->GetInteger() : 0;
 }
 
 int CPDF_FormField::CountSelectedOptions() const {
-  const CPDF_Array* pArray = ToArray(GetSelectedIndicesObject());
+  RetainPtr<const CPDF_Array> pArray = ToArray(GetSelectedIndicesObject());
   return pArray ? fxcrt::CollectionSize<int>(*pArray) : 0;
 }
 
@@ -708,7 +710,7 @@
   if (index < 0)
     return 0;
 
-  const CPDF_Array* pArray = ToArray(GetSelectedIndicesObject());
+  RetainPtr<const CPDF_Array> pArray = ToArray(GetSelectedIndicesObject());
   if (!pArray)
     return -1;
 
@@ -718,7 +720,7 @@
 }
 
 bool CPDF_FormField::IsSelectedOption(const WideString& wsOptValue) const {
-  const CPDF_Object* pValueObject = GetValueObject();
+  RetainPtr<const CPDF_Object> pValueObject = GetValueObject();
   if (!pValueObject)
     return false;
 
@@ -736,7 +738,8 @@
 }
 
 bool CPDF_FormField::IsSelectedIndex(int iOptIndex) const {
-  const CPDF_Object* pSelectedIndicesObject = GetSelectedIndicesObject();
+  RetainPtr<const CPDF_Object> pSelectedIndicesObject =
+      GetSelectedIndicesObject();
   if (!pSelectedIndicesObject)
     return false;
 
@@ -771,12 +774,13 @@
 bool CPDF_FormField::UseSelectedIndicesObject() const {
   DCHECK(GetType() == kComboBox || GetType() == kListBox);
 
-  const CPDF_Object* pSelectedIndicesObject = GetSelectedIndicesObject();
+  RetainPtr<const CPDF_Object> pSelectedIndicesObject =
+      GetSelectedIndicesObject();
   if (!pSelectedIndicesObject)
     return false;
 
   // If there's not value object, then just use the indices object.
-  const CPDF_Object* pValueObject = GetValueObject();
+  RetainPtr<const CPDF_Object> pValueObject = GetValueObject();
   if (!pValueObject)
     return true;
 
@@ -869,31 +873,32 @@
   }
 }
 
-const CPDF_Object* CPDF_FormField::GetFieldAttrInternal(
+RetainPtr<const CPDF_Object> CPDF_FormField::GetFieldAttrInternal(
     const ByteString& name) const {
-  return GetFieldAttrForDictInternal(m_pDict.Get(), name);
+  return GetFieldAttrRecursive(m_pDict.Get(), name, 0);
 }
 
 const CPDF_Dictionary* CPDF_FormField::GetFieldDictInternal() const {
   return m_pDict.Get();
 }
 
-const CPDF_Object* CPDF_FormField::GetDefaultValueObject() const {
+RetainPtr<const CPDF_Object> CPDF_FormField::GetDefaultValueObject() const {
   return GetFieldAttrInternal(pdfium::form_fields::kDV);
 }
 
-const CPDF_Object* CPDF_FormField::GetValueObject() const {
+RetainPtr<const CPDF_Object> CPDF_FormField::GetValueObject() const {
   return GetFieldAttrInternal(pdfium::form_fields::kV);
 }
 
-const CPDF_Object* CPDF_FormField::GetSelectedIndicesObject() const {
+RetainPtr<const CPDF_Object> CPDF_FormField::GetSelectedIndicesObject() const {
   DCHECK(GetType() == kComboBox || GetType() == kListBox);
   return GetFieldAttrInternal("I");
 }
 
-const CPDF_Object* CPDF_FormField::GetValueOrSelectedIndicesObject() const {
+RetainPtr<const CPDF_Object> CPDF_FormField::GetValueOrSelectedIndicesObject()
+    const {
   DCHECK(GetType() == kComboBox || GetType() == kListBox);
-  const CPDF_Object* pValue = GetValueObject();
+  RetainPtr<const CPDF_Object> pValue = GetValueObject();
   return pValue ? pValue : GetSelectedIndicesObject();
 }
 
diff --git a/core/fpdfdoc/cpdf_formfield.h b/core/fpdfdoc/cpdf_formfield.h
index 45896f9..e6e4e9b 100644
--- a/core/fpdfdoc/cpdf_formfield.h
+++ b/core/fpdfdoc/cpdf_formfield.h
@@ -155,17 +155,18 @@
   bool NotifyListOrComboBoxBeforeChange(const WideString& value);
   void NotifyListOrComboBoxAfterChange();
 
-  const CPDF_Object* GetFieldAttrInternal(const ByteString& name) const;
+  RetainPtr<const CPDF_Object> GetFieldAttrInternal(
+      const ByteString& name) const;
   const CPDF_Dictionary* GetFieldDictInternal() const;
-  const CPDF_Object* GetDefaultValueObject() const;
-  const CPDF_Object* GetValueObject() const;
+  RetainPtr<const CPDF_Object> GetDefaultValueObject() const;
+  RetainPtr<const CPDF_Object> GetValueObject() const;
 
   // For choice fields.
-  const CPDF_Object* GetSelectedIndicesObject() const;
+  RetainPtr<const CPDF_Object> GetSelectedIndicesObject() const;
 
   // For choice fields.
   // Value object takes precedence over selected indices object.
-  const CPDF_Object* GetValueOrSelectedIndicesObject() const;
+  RetainPtr<const CPDF_Object> GetValueOrSelectedIndicesObject() const;
 
   const std::vector<UnownedPtr<CPDF_FormControl>>& GetControls() const;