Protect owning layout item in all UpdateFWLData() overrides.
Also observe |this| in CFWL_DateTimePicker::SetEditText() and
ProcessSelChanged().
Bug: chromium:1053617,chromium:1052786,chromium:1040329
Change-Id: Icb4afcd7e5432787668355102b3b36faf5572894
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/66630
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fwl/cfwl_datetimepicker.cpp b/xfa/fwl/cfwl_datetimepicker.cpp
index 11ea810..3318f4d 100644
--- a/xfa/fwl/cfwl_datetimepicker.cpp
+++ b/xfa/fwl/cfwl_datetimepicker.cpp
@@ -162,7 +162,11 @@
if (!m_pEdit)
return;
- m_pEdit->SetText(wsText);
+ ObservedPtr<CFWL_DateTimePicker> watched(this);
+ m_pEdit->SetText(wsText); // JS may destroy |this|.
+ if (!watched)
+ return;
+
RepaintRect(m_rtClient);
CFWL_Event ev(CFWL_Event::Type::EditChanged);
@@ -307,8 +311,12 @@
m_iMonth = iMonth;
m_iDay = iDay;
+ ObservedPtr<CFWL_DateTimePicker> watched(this);
WideString wsText = FormatDateString(m_iYear, m_iMonth, m_iDay);
- m_pEdit->SetText(wsText);
+ m_pEdit->SetText(wsText); // JS may destroy |this|.
+ if (!watched)
+ return;
+
m_pEdit->Update();
RepaintRect(m_rtClient);
diff --git a/xfa/fxfa/cxfa_ffcheckbutton.cpp b/xfa/fxfa/cxfa_ffcheckbutton.cpp
index e9eb2bc..72e024c 100644
--- a/xfa/fxfa/cxfa_ffcheckbutton.cpp
+++ b/xfa/fxfa/cxfa_ffcheckbutton.cpp
@@ -292,8 +292,9 @@
if (!GetNormalWidget())
return false;
- XFA_CHECKSTATE eState = m_pNode->GetCheckState();
- SetFWLCheckState(eState);
+ // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
+ RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
+ SetFWLCheckState(m_pNode->GetCheckState());
GetNormalWidget()->Update();
return true;
}
diff --git a/xfa/fxfa/cxfa_ffcombobox.cpp b/xfa/fxfa/cxfa_ffcombobox.cpp
index 79a750f..2f89ce2 100644
--- a/xfa/fxfa/cxfa_ffcombobox.cpp
+++ b/xfa/fxfa/cxfa_ffcombobox.cpp
@@ -201,6 +201,8 @@
if (!pComboBox)
return false;
+ // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
+ RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
std::vector<int32_t> iSelArray = m_pNode->GetSelectedItems();
if (!iSelArray.empty()) {
pComboBox->SetCurSel(iSelArray.front());
diff --git a/xfa/fxfa/cxfa_ffdatetimeedit.cpp b/xfa/fxfa/cxfa_ffdatetimeedit.cpp
index 5f74ec0..a0fcd26 100644
--- a/xfa/fxfa/cxfa_ffdatetimeedit.cpp
+++ b/xfa/fxfa/cxfa_ffdatetimeedit.cpp
@@ -155,6 +155,8 @@
if (!GetNormalWidget())
return false;
+ // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
+ RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
if (IsFocused())
eType = XFA_VALUEPICTURE_Edit;
diff --git a/xfa/fxfa/cxfa_fflistbox.cpp b/xfa/fxfa/cxfa_fflistbox.cpp
index df7955e..fe55303 100644
--- a/xfa/fxfa/cxfa_fflistbox.cpp
+++ b/xfa/fxfa/cxfa_fflistbox.cpp
@@ -139,10 +139,13 @@
}
bool CXFA_FFListBox::UpdateFWLData() {
- if (!GetNormalWidget())
+ auto* pListBox = ToListBox(GetNormalWidget());
+ if (!pListBox)
return false;
- auto* pListBox = ToListBox(GetNormalWidget());
+ // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
+ RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
+
std::vector<int32_t> iSelArray = m_pNode->GetSelectedItems();
std::vector<CFWL_ListItem*> selItemArray(iSelArray.size());
std::transform(iSelArray.begin(), iSelArray.end(), selItemArray.begin(),
diff --git a/xfa/fxfa/cxfa_fftextedit.cpp b/xfa/fxfa/cxfa_fftextedit.cpp
index 52ce7ab..8ddc2ff 100644
--- a/xfa/fxfa/cxfa_fftextedit.cpp
+++ b/xfa/fxfa/cxfa_fftextedit.cpp
@@ -279,10 +279,12 @@
}
bool CXFA_FFTextEdit::UpdateFWLData() {
- if (!GetNormalWidget())
+ CFWL_Edit* pEdit = ToEdit(GetNormalWidget());
+ if (!pEdit)
return false;
- CFWL_Edit* pEdit = ToEdit(GetNormalWidget());
+ // Prevents destruction of the CXFA_ContentLayoutItem that owns |this|.
+ RetainPtr<CXFA_ContentLayoutItem> retainer(m_pLayoutItem.Get());
XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
if (IsFocused())
eType = XFA_VALUEPICTURE_Edit;
@@ -310,7 +312,6 @@
pEdit->SetLimit(nDataLen);
bUpdate = true;
}
-
WideString wsText = m_pNode->GetValue(eType);
WideString wsOldText = pEdit->GetText();
if (wsText != wsOldText || (eType == XFA_VALUEPICTURE_Edit && bUpdate)) {