Return retained objects from CPDF_FormField methods.

Removes last unretained locals from CPDF_InteractiveForm.

Change-Id: If7cc1b064546acdcdbce75a02893996c6ad0692e
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/100110
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfdoc/cpdf_annotlist.cpp b/core/fpdfdoc/cpdf_annotlist.cpp
index 7bb8fe1..be45371 100644
--- a/core/fpdfdoc/cpdf_annotlist.cpp
+++ b/core/fpdfdoc/cpdf_annotlist.cpp
@@ -128,7 +128,7 @@
     return;
   }
 
-  CPDF_Object* pFieldTypeObj =
+  RetainPtr<const CPDF_Object> pFieldTypeObj =
       CPDF_FormField::GetFieldAttrForDict(pAnnotDict, pdfium::form_fields::kFT);
   if (!pFieldTypeObj)
     return;
@@ -140,7 +140,7 @@
     return;
   }
 
-  CPDF_Object* pFieldFlagsObj =
+  RetainPtr<const CPDF_Object> pFieldFlagsObj =
       CPDF_FormField::GetFieldAttrForDict(pAnnotDict, pdfium::form_fields::kFf);
   uint32_t flags = pFieldFlagsObj ? pFieldFlagsObj->GetInteger() : 0;
   if (field_type == pdfium::form_fields::kCh) {
diff --git a/core/fpdfdoc/cpdf_bafontmap.cpp b/core/fpdfdoc/cpdf_bafontmap.cpp
index 57e34fa..1edb015 100644
--- a/core/fpdfdoc/cpdf_bafontmap.cpp
+++ b/core/fpdfdoc/cpdf_bafontmap.cpp
@@ -237,7 +237,7 @@
   }
 
   ByteString sDA;
-  const CPDF_Object* pObj =
+  RetainPtr<const CPDF_Object> pObj =
       CPDF_FormField::GetFieldAttrForDict(m_pAnnotDict.Get(), "DA");
   if (pObj)
     sDA = pObj->GetString();
diff --git a/core/fpdfdoc/cpdf_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp
index f725ec2..ea1001c 100644
--- a/core/fpdfdoc/cpdf_formcontrol.cpp
+++ b/core/fpdfdoc/cpdf_formcontrol.cpp
@@ -86,7 +86,7 @@
   DCHECK(GetType() == CPDF_FormField::kCheckBox ||
          GetType() == CPDF_FormField::kRadioButton);
   ByteString csOn = GetOnStateName();
-  const CPDF_Array* pArray = ToArray(m_pField->GetFieldAttr("Opt"));
+  RetainPtr<const CPDF_Array> pArray = ToArray(m_pField->GetFieldAttr("Opt"));
   if (pArray)
     csOn = pArray->GetByteStringAt(m_pField->GetControlIndex(this));
   if (csOn.IsEmpty())
@@ -105,7 +105,7 @@
 bool CPDF_FormControl::IsDefaultChecked() const {
   DCHECK(GetType() == CPDF_FormField::kCheckBox ||
          GetType() == CPDF_FormField::kRadioButton);
-  const CPDF_Object* pDV = m_pField->GetFieldAttr("DV");
+  RetainPtr<const CPDF_Object> pDV = m_pField->GetFieldAttr("DV");
   if (!pDV)
     return false;
 
@@ -184,11 +184,12 @@
     return CPDF_DefaultAppearance(
         m_pWidgetDict->GetByteStringFor(pdfium::form_fields::kDA));
   }
-  const CPDF_Object* pObj = m_pField->GetFieldAttr(pdfium::form_fields::kDA);
-  if (!pObj)
-    return m_pForm->GetDefaultAppearance();
+  RetainPtr<const CPDF_Object> pObj =
+      m_pField->GetFieldAttr(pdfium::form_fields::kDA);
+  if (pObj)
+    return CPDF_DefaultAppearance(pObj->GetString());
 
-  return CPDF_DefaultAppearance(pObj->GetString());
+  return m_pForm->GetDefaultAppearance();
 }
 
 absl::optional<WideString> CPDF_FormControl::GetDefaultControlFontName() const {
@@ -206,10 +207,10 @@
   if (!csFontNameTag.has_value() || csFontNameTag->IsEmpty())
     return nullptr;
 
-  CPDF_Object* pObj =
-      CPDF_FormField::GetFieldAttrForDict(m_pWidgetDict.Get(), "DR");
-  if (CPDF_Dictionary* pDict = ToDictionary(pObj)) {
-    RetainPtr<CPDF_Dictionary> pFonts = pDict->GetMutableDictFor("Font");
+  RetainPtr<CPDF_Dictionary> pDRDict = ToDictionary(
+      CPDF_FormField::GetMutableFieldAttrForDict(m_pWidgetDict.Get(), "DR"));
+  if (pDRDict) {
+    RetainPtr<CPDF_Dictionary> pFonts = pDRDict->GetMutableDictFor("Font");
     if (ValidateFontResourceDict(pFonts.Get())) {
       RetainPtr<CPDF_Dictionary> pElement =
           pFonts->GetMutableDictFor(csFontNameTag.value());
@@ -226,8 +227,8 @@
     return pFormFont;
 
   RetainPtr<CPDF_Dictionary> pPageDict = m_pWidgetDict->GetMutableDictFor("P");
-  CPDF_Dictionary* pDict = ToDictionary(
-      CPDF_FormField::GetFieldAttrForDict(pPageDict.Get(), "Resources"));
+  RetainPtr<CPDF_Dictionary> pDict = ToDictionary(
+      CPDF_FormField::GetMutableFieldAttrForDict(pPageDict.Get(), "Resources"));
   if (!pDict)
     return nullptr;
 
@@ -247,7 +248,8 @@
   if (m_pWidgetDict->KeyExist(pdfium::form_fields::kQ))
     return m_pWidgetDict->GetIntegerFor(pdfium::form_fields::kQ, 0);
 
-  const CPDF_Object* pObj = m_pField->GetFieldAttr(pdfium::form_fields::kQ);
+  RetainPtr<const CPDF_Object> pObj =
+      m_pField->GetFieldAttr(pdfium::form_fields::kQ);
   if (pObj)
     return pObj->GetInteger();
 
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index 8d5fec6..b688345 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -49,6 +49,12 @@
       nLevel + 1);
 }
 
+const CPDF_Object* GetFieldAttrForDictInternal(
+    const CPDF_Dictionary* pFieldDict,
+    const ByteString& name) {
+  return GetFieldAttrRecursive(pFieldDict, name, 0);
+}
+
 }  // namespace
 
 // static
@@ -61,17 +67,18 @@
 }
 
 // static
-const CPDF_Object* CPDF_FormField::GetFieldAttrForDict(
+RetainPtr<const CPDF_Object> CPDF_FormField::GetFieldAttrForDict(
     const CPDF_Dictionary* pFieldDict,
     const ByteString& name) {
-  return GetFieldAttrRecursive(pFieldDict, name, 0);
+  return pdfium::WrapRetain(GetFieldAttrForDictInternal(pFieldDict, name));
 }
 
 // static
-CPDF_Object* CPDF_FormField::GetFieldAttrForDict(CPDF_Dictionary* pFieldDict,
-                                                 const ByteString& name) {
-  return const_cast<CPDF_Object*>(GetFieldAttrRecursive(
-      static_cast<const CPDF_Dictionary*>(pFieldDict), name, 0));
+RetainPtr<CPDF_Object> CPDF_FormField::GetMutableFieldAttrForDict(
+    CPDF_Dictionary* pFieldDict,
+    const ByteString& name) {
+  return pdfium::WrapRetain(
+      const_cast<CPDF_Object*>(GetFieldAttrForDictInternal(pFieldDict, name)));
 }
 
 // static
@@ -105,7 +112,7 @@
 CPDF_FormField::~CPDF_FormField() = default;
 
 void CPDF_FormField::InitFieldFlags() {
-  const CPDF_Object* ft_attr = GetFieldAttr(pdfium::form_fields::kFT);
+  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;
@@ -145,6 +152,15 @@
   return GetFullNameForDict(m_pDict.Get());
 }
 
+RetainPtr<const CPDF_Object> CPDF_FormField::GetFieldAttr(
+    const ByteString& name) const {
+  return pdfium::WrapRetain(GetFieldAttrInternal(name));
+}
+
+RetainPtr<const CPDF_Dictionary> CPDF_FormField::GetFieldDict() const {
+  return pdfium::WrapRetain(GetFieldDictInternal());
+}
+
 bool CPDF_FormField::ResetField() {
   switch (m_Type) {
     case kCheckBox:
@@ -191,7 +207,7 @@
           csValue = pV->GetUnicodeText();
       }
 
-      bool bHasRV = !!GetFieldAttr(pdfium::form_fields::kRV);
+      bool bHasRV = !!GetFieldAttrInternal(pdfium::form_fields::kRV);
       if (!bHasRV && (csDValue == csValue))
         return false;
 
@@ -267,22 +283,22 @@
 }
 
 CPDF_AAction CPDF_FormField::GetAdditionalAction() const {
-  const CPDF_Object* pObj = GetFieldAttr(pdfium::form_fields::kAA);
+  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 = GetFieldAttr(pdfium::form_fields::kTU);
+  const CPDF_Object* pObj = GetFieldAttrInternal(pdfium::form_fields::kTU);
   return pObj ? pObj->GetUnicodeText() : WideString();
 }
 
 WideString CPDF_FormField::GetMappingName() const {
-  const CPDF_Object* pObj = GetFieldAttr(pdfium::form_fields::kTM);
+  const CPDF_Object* pObj = GetFieldAttrInternal(pdfium::form_fields::kTM);
   return pObj ? pObj->GetUnicodeText() : WideString();
 }
 
 uint32_t CPDF_FormField::GetFieldFlags() const {
-  const CPDF_Object* pObj = GetFieldAttr(pdfium::form_fields::kFf);
+  const CPDF_Object* pObj = GetFieldAttrInternal(pdfium::form_fields::kFf);
   return pObj ? pObj->GetInteger() : 0;
 }
 
@@ -397,7 +413,7 @@
 }
 
 int CPDF_FormField::GetMaxLen() const {
-  const CPDF_Object* pObj = GetFieldAttr("MaxLen");
+  const CPDF_Object* pObj = GetFieldAttrInternal("MaxLen");
   if (pObj)
     return pObj->GetInteger();
 
@@ -547,12 +563,12 @@
 }
 
 int CPDF_FormField::CountOptions() const {
-  const CPDF_Array* pArray = ToArray(GetFieldAttr("Opt"));
+  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(GetFieldAttr("Opt"));
+  const CPDF_Array* pArray = ToArray(GetFieldAttrInternal("Opt"));
   if (!pArray)
     return WideString();
 
@@ -619,7 +635,7 @@
     }
   }
 
-  const CPDF_Object* pOpt = GetFieldAttr("Opt");
+  const CPDF_Object* pOpt = GetFieldAttrInternal("Opt");
   if (!ToArray(pOpt)) {
     ByteString csBExport = PDF_EncodeText(csWExport.AsStringView());
     if (bChecked) {
@@ -679,7 +695,7 @@
 }
 
 int CPDF_FormField::GetTopVisibleIndex() const {
-  const CPDF_Object* pObj = GetFieldAttr("TI");
+  const CPDF_Object* pObj = GetFieldAttrInternal("TI");
   return pObj ? pObj->GetInteger() : 0;
 }
 
@@ -853,17 +869,26 @@
   }
 }
 
+const CPDF_Object* CPDF_FormField::GetFieldAttrInternal(
+    const ByteString& name) const {
+  return GetFieldAttrForDictInternal(m_pDict.Get(), name);
+}
+
+const CPDF_Dictionary* CPDF_FormField::GetFieldDictInternal() const {
+  return m_pDict.Get();
+}
+
 const CPDF_Object* CPDF_FormField::GetDefaultValueObject() const {
-  return GetFieldAttr(pdfium::form_fields::kDV);
+  return GetFieldAttrInternal(pdfium::form_fields::kDV);
 }
 
 const CPDF_Object* CPDF_FormField::GetValueObject() const {
-  return GetFieldAttr(pdfium::form_fields::kV);
+  return GetFieldAttrInternal(pdfium::form_fields::kV);
 }
 
 const CPDF_Object* CPDF_FormField::GetSelectedIndicesObject() const {
   DCHECK(GetType() == kComboBox || GetType() == kListBox);
-  return GetFieldAttr("I");
+  return GetFieldAttrInternal("I");
 }
 
 const CPDF_Object* CPDF_FormField::GetValueOrSelectedIndicesObject() const {
diff --git a/core/fpdfdoc/cpdf_formfield.h b/core/fpdfdoc/cpdf_formfield.h
index b7e19af..4c7814d 100644
--- a/core/fpdfdoc/cpdf_formfield.h
+++ b/core/fpdfdoc/cpdf_formfield.h
@@ -74,20 +74,18 @@
 
   static absl::optional<FormFieldType> IntToFormFieldType(int value);
   static WideString GetFullNameForDict(const CPDF_Dictionary* pFieldDict);
-  static const CPDF_Object* GetFieldAttrForDict(
+  static RetainPtr<const CPDF_Object> GetFieldAttrForDict(
       const CPDF_Dictionary* pFieldDict,
       const ByteString& name);
-  static CPDF_Object* GetFieldAttrForDict(CPDF_Dictionary* pFieldDict,
-                                          const ByteString& name);
+  static RetainPtr<CPDF_Object> GetMutableFieldAttrForDict(
+      CPDF_Dictionary* pFieldDict,
+      const ByteString& name);
 
   WideString GetFullName() const;
   Type GetType() const { return m_Type; }
 
-  const CPDF_Object* GetFieldAttr(const ByteString& name) const {
-    return GetFieldAttrForDict(m_pDict.Get(), name);
-  }
-
-  const CPDF_Dictionary* GetFieldDict() const { return m_pDict.Get(); }
+  RetainPtr<const CPDF_Object> GetFieldAttr(const ByteString& name) const;
+  RetainPtr<const CPDF_Dictionary> GetFieldDict() const;
   bool ResetField();
 
   int CountControls() const;
@@ -157,6 +155,8 @@
   bool NotifyListOrComboBoxBeforeChange(const WideString& value);
   void NotifyListOrComboBoxAfterChange();
 
+  const CPDF_Object* GetFieldAttrInternal(const ByteString& name) const;
+  const CPDF_Dictionary* GetFieldDictInternal() const;
   const CPDF_Object* GetDefaultValueObject() const;
   const CPDF_Object* GetValueObject() const;
 
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index 50addf6..42f85ac 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -916,7 +916,8 @@
     return;
 
   ByteString DA;
-  CPDF_Object* pDAObj = CPDF_FormField::GetFieldAttrForDict(pAnnotDict, "DA");
+  RetainPtr<const CPDF_Object> pDAObj =
+      CPDF_FormField::GetFieldAttrForDict(pAnnotDict, "DA");
   if (pDAObj)
     DA = pDAObj->GetString();
   if (DA.IsEmpty())
@@ -1095,16 +1096,16 @@
 
   switch (type) {
     case CPDF_GenerateAP::kTextField: {
-      const CPDF_Object* pV = CPDF_FormField::GetFieldAttrForDict(
+      RetainPtr<const CPDF_Object> pV = CPDF_FormField::GetFieldAttrForDict(
           pAnnotDict, pdfium::form_fields::kV);
       WideString swValue = pV ? pV->GetUnicodeText() : WideString();
-      const CPDF_Object* pQ =
+      RetainPtr<const CPDF_Object> pQ =
           CPDF_FormField::GetFieldAttrForDict(pAnnotDict, "Q");
       int32_t nAlign = pQ ? pQ->GetInteger() : 0;
-      const CPDF_Object* pFf = CPDF_FormField::GetFieldAttrForDict(
+      RetainPtr<const CPDF_Object> pFf = CPDF_FormField::GetFieldAttrForDict(
           pAnnotDict, pdfium::form_fields::kFf);
       uint32_t dwFlags = pFf ? pFf->GetInteger() : 0;
-      const CPDF_Object* pMaxLen =
+      RetainPtr<const CPDF_Object> pMaxLen =
           CPDF_FormField::GetFieldAttrForDict(pAnnotDict, "MaxLen");
       uint32_t dwMaxLen = pMaxLen ? pMaxLen->GetInteger() : 0;
       CPVT_VariableText vt(&prd);
@@ -1159,7 +1160,7 @@
       break;
     }
     case CPDF_GenerateAP::kComboBox: {
-      const CPDF_Object* pV = CPDF_FormField::GetFieldAttrForDict(
+      RetainPtr<const CPDF_Object> pV = CPDF_FormField::GetFieldAttrForDict(
           pAnnotDict, pdfium::form_fields::kV);
       WideString swValue = pV ? pV->GetUnicodeText() : WideString();
       CPVT_VariableText vt(&prd);
@@ -1226,11 +1227,12 @@
       break;
     }
     case CPDF_GenerateAP::kListBox: {
-      CPDF_Array* pOpts =
+      RetainPtr<const CPDF_Array> pOpts =
           ToArray(CPDF_FormField::GetFieldAttrForDict(pAnnotDict, "Opt"));
-      CPDF_Array* pSels =
+      RetainPtr<const CPDF_Array> pSels =
           ToArray(CPDF_FormField::GetFieldAttrForDict(pAnnotDict, "I"));
-      CPDF_Object* pTi = CPDF_FormField::GetFieldAttrForDict(pAnnotDict, "TI");
+      RetainPtr<const CPDF_Object> pTi =
+          CPDF_FormField::GetFieldAttrForDict(pAnnotDict, "TI");
       int32_t nTop = pTi ? pTi->GetInteger() : 0;
       fxcrt::ostringstream sBody;
       if (pOpts) {
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index b2bfe40..5d21c03 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -909,7 +909,7 @@
     if (fields)
       bFind = pdfium::Contains(*fields, pField);
     if (bIncludeOrExclude == bFind) {
-      const CPDF_Dictionary* pFieldDict = pField->GetFieldDict();
+      RetainPtr<const CPDF_Dictionary> pFieldDict = pField->GetFieldDict();
       if (pField->IsRequired() &&
           pFieldDict->GetByteStringFor(pdfium::form_fields::kV).IsEmpty()) {
         return false;
@@ -980,7 +980,7 @@
         pField->GetType() == CPDF_FormField::kRadioButton) {
       WideString csExport = pField->GetCheckValue(false);
       ByteString csBExport = PDF_EncodeText(csExport.AsStringView());
-      const CPDF_Object* pOpt = pField->GetFieldAttr("Opt");
+      RetainPtr<const CPDF_Object> pOpt = pField->GetFieldAttr("Opt");
       if (pOpt) {
         pFieldDict->SetNewFor<CPDF_String>(pdfium::form_fields::kV, csBExport,
                                            false);
@@ -988,7 +988,8 @@
         pFieldDict->SetNewFor<CPDF_Name>(pdfium::form_fields::kV, csBExport);
       }
     } else {
-      const CPDF_Object* pV = pField->GetFieldAttr(pdfium::form_fields::kV);
+      RetainPtr<const CPDF_Object> pV =
+          pField->GetFieldAttr(pdfium::form_fields::kV);
       if (pV)
         pFieldDict->SetFor(pdfium::form_fields::kV, pV->CloneDirectObject());
     }