Prevent a UAF in CPDFSDK_Widget::HasXFAAAction().
Calling GetMixXFAWidget() and GetGroupMixXFAWidget() can trigger JS and
invalidate widgets returned by previous calls. Use ObservedPtr to check
for CXFA_FFWidget destruction to catch this. Apply the same fix to
CPDFSDK_Widget::OnXFAAAction().
Bug: chromium:981528
Change-Id: I4d6cdd05135ccd7f57d53e8d011422de01921191
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/57353
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
index 5309c49..8a6f3c2 100644
--- a/fpdfsdk/cpdfsdk_widget.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -176,8 +176,8 @@
}
bool CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) const {
- CXFA_FFWidget* hWidget = GetMixXFAWidget();
- if (!hWidget)
+ ObservedPtr<CXFA_FFWidget> pWidget(GetMixXFAWidget());
+ if (!pWidget)
return false;
CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
@@ -196,7 +196,12 @@
}
}
}
- CXFA_Node* node = hWidget->GetNode();
+
+ // Check |pWidget| again because JS may have destroyed it in the block above.
+ if (!pWidget)
+ return false;
+
+ CXFA_Node* node = pWidget->GetNode();
if (!node->IsWidgetReady())
return false;
return pXFAWidgetHandler->HasEvent(node, eEventType);
@@ -207,8 +212,8 @@
CPDFSDK_PageView* pPageView) {
CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
- CXFA_FFWidget* hWidget = GetMixXFAWidget();
- if (!hWidget)
+ ObservedPtr<CXFA_FFWidget> pWidget(GetMixXFAWidget());
+ if (!pWidget)
return false;
XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
@@ -245,8 +250,12 @@
}
}
+ // Check |pWidget| again because JS may have destroyed it in the block above.
+ if (!pWidget)
+ return false;
+
XFA_EventError nRet = XFA_EventError::kNotExist;
- CXFA_Node* node = hWidget->GetNode();
+ CXFA_Node* node = pWidget->GetNode();
if (node->IsWidgetReady()) {
param.m_pTarget = node;
nRet = pXFAWidgetHandler->ProcessEvent(node, ¶m);