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;