Retain corresponding layoutitem in CXFA_FFDocView::SetFocus(). Prevent destruction of the newly focused widget. Remove the need for an ObserverPtr, and potential nullptr dereference with the ObserverPtr. Bug: chromium:982193 Change-Id: I1e210c91ab90f90a6d3fc7de9d83dd1427e97f0d Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/66713 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp index 3a44122..62b2fb2 100644 --- a/xfa/fxfa/cxfa_ffdocview.cpp +++ b/xfa/fxfa/cxfa_ffdocview.cpp
@@ -291,7 +291,10 @@ if (pNewFocus == m_pFocusWidget) return false; - ObservedPtr<CXFA_FFWidget> pNewWatched(pNewFocus); + // Prevents destruction of the CXFA_ContentLayoutItem that owns |pNewFocus|. + RetainPtr<CXFA_ContentLayoutItem> retain_layout( + pNewFocus ? pNewFocus->GetLayoutItem() : nullptr); + if (m_pFocusWidget) { CXFA_ContentLayoutItem* pItem = m_pFocusWidget->GetLayoutItem(); if (pItem->TestStatusBits(XFA_WidgetStatus_Visible) && @@ -303,23 +306,22 @@ } } if (m_pFocusWidget) { - if (!m_pFocusWidget->OnKillFocus(pNewWatched.Get())) + if (!m_pFocusWidget->OnKillFocus(pNewFocus)) return false; } - if (pNewWatched) { - if (pNewWatched->GetLayoutItem()->TestStatusBits( - XFA_WidgetStatus_Visible)) { - if (!pNewWatched->IsLoaded()) - pNewWatched->LoadWidget(); - if (!pNewWatched->OnSetFocus(m_pFocusWidget.Get())) - pNewWatched.Reset(); + if (pNewFocus) { + if (pNewFocus->GetLayoutItem()->TestStatusBits(XFA_WidgetStatus_Visible)) { + if (!pNewFocus->IsLoaded()) + pNewFocus->LoadWidget(); + if (!pNewFocus->OnSetFocus(m_pFocusWidget.Get())) + pNewFocus = nullptr; } } - if (pNewWatched) { - CXFA_Node* node = pNewWatched->GetNode(); + if (pNewFocus) { + CXFA_Node* node = pNewFocus->GetNode(); m_pFocusNode = node->IsWidgetReady() ? node : nullptr; - m_pFocusWidget.Reset(pNewWatched.Get()); + m_pFocusWidget.Reset(pNewFocus); } else { m_pFocusNode.Reset(); m_pFocusWidget.Reset();