Keep CPWL_Wnd more contained within CFFL_FormField classes.

Avoid manipulations by the interactive formfiller itself.

Change-Id: Ic534e197e645638314da44d74fa6185998a85122
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/96414
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/formfiller/cffl_formfield.cpp b/fpdfsdk/formfiller/cffl_formfield.cpp
index 97b5bd0..013e7a6 100644
--- a/fpdfsdk/formfiller/cffl_formfield.cpp
+++ b/fpdfsdk/formfiller/cffl_formfield.cpp
@@ -368,8 +368,8 @@
   if (pPrivateData->AppearanceAgeEquals(m_pWidget->GetAppearanceAge()))
     return pWnd;
 
-  return ResetPWLWindowForValueAge(pPageView, m_pWidget,
-                                   pPrivateData->GetValueAge());
+  return ResetPWLWindowForValueAgeInternal(pPageView, m_pWidget,
+                                           pPrivateData->GetValueAge());
 }
 
 void CFFL_FormField::DestroyPWLWindow(const CPDFSDK_PageView* pPageView) {
@@ -533,7 +533,24 @@
 void CFFL_FormField::RecreatePWLWindowFromSavedState(
     const CPDFSDK_PageView* pPageView) {}
 
-CPWL_Wnd* CFFL_FormField::ResetPWLWindowForValueAge(
+CFFL_PerWindowData* CFFL_FormField::GetPerPWLWindowData(
+    const CPDFSDK_PageView* pPageView) {
+  CPWL_Wnd* pWnd = GetPWLWindow(pPageView);
+  if (!pWnd)
+    return nullptr;
+
+  return static_cast<CFFL_PerWindowData*>(pWnd->GetAttachedData());
+}
+
+void CFFL_FormField::ResetPWLWindowForValueAge(
+    const CPDFSDK_PageView* pPageView,
+    CPDFSDK_Widget* pWidget,
+    uint32_t nValueAge) {
+  // Don't leak PWL_Wnd result to public callers.
+  ResetPWLWindowForValueAgeInternal(pPageView, pWidget, nValueAge);
+}
+
+CPWL_Wnd* CFFL_FormField::ResetPWLWindowForValueAgeInternal(
     const CPDFSDK_PageView* pPageView,
     CPDFSDK_Widget* pWidget,
     uint32_t nValueAge) {
diff --git a/fpdfsdk/formfiller/cffl_formfield.h b/fpdfsdk/formfiller/cffl_formfield.h
index a9479f8..e3c1b98 100644
--- a/fpdfsdk/formfiller/cffl_formfield.h
+++ b/fpdfsdk/formfiller/cffl_formfield.h
@@ -19,6 +19,7 @@
 #include "fpdfsdk/pwl/cpwl_wnd.h"
 #include "fpdfsdk/pwl/ipwl_fillernotify.h"
 
+class CFFL_PerWindowData;
 class CPDFSDK_PageView;
 class CPDFSDK_Widget;
 
@@ -122,11 +123,6 @@
   CFX_PointF FFLtoPWL(const CFX_PointF& point);
   CFX_PointF PWLtoFFL(const CFX_PointF& point);
   bool CommitData(const CPDFSDK_PageView* pPageView, Mask<FWL_EVENTFLAG> nFlag);
-  CPWL_Wnd* ResetPWLWindowForValueAge(const CPDFSDK_PageView* pPageView,
-                                      CPDFSDK_Widget* pWidget,
-                                      uint32_t nValueAge);
-  CPWL_Wnd* GetPWLWindow(const CPDFSDK_PageView* pPageView) const;
-  CPWL_Wnd* CreateOrUpdatePWLWindow(const CPDFSDK_PageView* pPageView);
   void DestroyPWLWindow(const CPDFSDK_PageView* pPageView);
   void EscapeFiller(CPDFSDK_PageView* pPageView, bool bDestroyPWLWindow);
 
@@ -138,10 +134,25 @@
 
   CPDFSDK_Widget* GetSDKWidget() const { return m_pWidget.Get(); }
 
+  CFFL_PerWindowData* GetPerPWLWindowData(const CPDFSDK_PageView* pPageView);
+  void ResetPWLWindowForValueAge(const CPDFSDK_PageView* pPageView,
+                                 CPDFSDK_Widget* pWidget,
+                                 uint32_t nValueAge);
+
  protected:
+  friend class CPWLComboBoxEditEmbedderTest;
+  friend class CPWLEditEmbedderTest;
+  friend class CPWLSpecialButtonEmbedderTest;
+
   virtual CPWL_Wnd* ResetPWLWindow(const CPDFSDK_PageView* pPageView);
   virtual CPWL_Wnd* RestorePWLWindow(const CPDFSDK_PageView* pPageView);
 
+  CPWL_Wnd* GetPWLWindow(const CPDFSDK_PageView* pPageView) const;
+  CPWL_Wnd* CreateOrUpdatePWLWindow(const CPDFSDK_PageView* pPageView);
+  CPWL_Wnd* ResetPWLWindowForValueAgeInternal(const CPDFSDK_PageView* pPageView,
+                                              CPDFSDK_Widget* pWidget,
+                                              uint32_t nValueAge);
+
   // If the inheriting widget has its own fontmap and a PWL_Edit widget that
   // access that fontmap then you have to call DestroyWindows before destroying
   // the font map in order to not get a use-after-free.
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
index 399608f..6f57daa 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
@@ -917,13 +917,11 @@
 
   bool bExit = false;
   if (nAge != pWidget->GetAppearanceAge()) {
-    CPWL_Wnd* pWnd = pFormField->ResetPWLWindowForValueAge(
-        pPageView, pWidget.Get(), nValueAge);
-    if (!pWnd)
+    pFormField->ResetPWLWindowForValueAge(pPageView, pWidget.Get(), nValueAge);
+    pPrivateData = pFormField->GetPerPWLWindowData(pPageView);
+    if (!pPrivateData)
       return {true, true};
 
-    pPrivateData =
-        static_cast<const CFFL_PerWindowData*>(pWnd->GetAttachedData());
     pWidget.Reset(pPrivateData->GetWidget());
     pPageView = pPrivateData->GetPageView();
     bExit = true;