From 31781107f6bda92e732fed805f62e8512bc78149 Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Mon, 16 Jul 2018 21:17:46 +0000 Subject: Fix crash when typing letters into an XFA datetime field. The root of the issue is that CXFA_FFDateTimeEdit inherits from CXFA_FFTextEdit and methods in the former treat its widget as a CFWL_Edit, while it can be a CFWL_DateTimePicker. Bug: chromium:857521 Change-Id: I764b6c03095b16f6a9cf72ff36768ca4c57c4070 Reviewed-on: https://pdfium-review.googlesource.com/37910 Reviewed-by: Ryan Harrison Commit-Queue: Henrique Nakashima --- xfa/fwl/cfwl_datetimepicker.cpp | 44 +++++++++++++++++++ xfa/fwl/cfwl_datetimepicker.h | 11 +++++ xfa/fxfa/cxfa_ffdatetimeedit.cpp | 94 +++++++++++++++++++++++++++++++++------- xfa/fxfa/cxfa_ffdatetimeedit.h | 20 +++++++++ 4 files changed, 154 insertions(+), 15 deletions(-) diff --git a/xfa/fwl/cfwl_datetimepicker.cpp b/xfa/fwl/cfwl_datetimepicker.cpp index 8c37e1dbe8..0af01fb2a1 100644 --- a/xfa/fwl/cfwl_datetimepicker.cpp +++ b/xfa/fwl/cfwl_datetimepicker.cpp @@ -178,6 +178,10 @@ WideString CFWL_DateTimePicker::GetEditText() const { return m_pEdit ? m_pEdit->GetText() : L""; } +int32_t CFWL_DateTimePicker::GetEditTextLength() const { + return m_pEdit ? m_pEdit->GetTextLength() : 0; +} + CFX_RectF CFWL_DateTimePicker::GetBBox() const { CFX_RectF rect = m_pProperties->m_rtWidget; if (NeedsToShowButton()) @@ -460,3 +464,43 @@ void CFWL_DateTimePicker::GetPopupPos(float fMinHeight, m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor, pPopupRect); } + +void CFWL_DateTimePicker::ClearText() { + m_pEdit->ClearText(); +} + +void CFWL_DateTimePicker::SelectAll() { + m_pEdit->SelectAll(); +} + +void CFWL_DateTimePicker::ClearSelection() { + m_pEdit->ClearSelection(); +} + +Optional CFWL_DateTimePicker::Copy() { + return m_pEdit->Copy(); +} + +Optional CFWL_DateTimePicker::Cut() { + return m_pEdit->Cut(); +} + +bool CFWL_DateTimePicker::Paste(const WideString& wsPaste) { + return m_pEdit->Paste(wsPaste); +} + +bool CFWL_DateTimePicker::Undo() { + return m_pEdit->Undo(); +} + +bool CFWL_DateTimePicker::Redo() { + return m_pEdit->Redo(); +} + +bool CFWL_DateTimePicker::CanUndo() { + return m_pEdit->CanUndo(); +} + +bool CFWL_DateTimePicker::CanRedo() { + return m_pEdit->CanRedo(); +} diff --git a/xfa/fwl/cfwl_datetimepicker.h b/xfa/fwl/cfwl_datetimepicker.h index 00e7f61d73..f80f09d1bf 100644 --- a/xfa/fwl/cfwl_datetimepicker.h +++ b/xfa/fwl/cfwl_datetimepicker.h @@ -49,13 +49,24 @@ class CFWL_DateTimePicker : public CFWL_Widget { void SetCurSel(int32_t iYear, int32_t iMonth, int32_t iDay); void SetEditText(const WideString& wsText); + int32_t GetEditTextLength() const; WideString GetEditText() const; + void ClearText(); + void SelectAll(); + void ClearSelection(); bool HasSelection() const { return m_pEdit->HasSelection(); } // Returns of the selection. std::pair GetSelection() const { return m_pEdit->GetSelection(); } + Optional Copy(); + Optional Cut(); + bool Paste(const WideString& wsPaste); + bool Undo(); + bool Redo(); + bool CanUndo(); + bool CanRedo(); CFX_RectF GetBBox() const; void SetEditLimit(int32_t nLimit) { m_pEdit->SetLimit(nLimit); } diff --git a/xfa/fxfa/cxfa_ffdatetimeedit.cpp b/xfa/fxfa/cxfa_ffdatetimeedit.cpp index f5531ffd66..6218e29826 100644 --- a/xfa/fxfa/cxfa_ffdatetimeedit.cpp +++ b/xfa/fxfa/cxfa_ffdatetimeedit.cpp @@ -24,6 +24,10 @@ CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_Node* pNode) CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {} +CFWL_DateTimePicker* CXFA_FFDateTimeEdit::GetPickerWidget() { + return static_cast(m_pNormalWidget.get()); +} + CFX_RectF CXFA_FFDateTimeEdit::GetBBox(uint32_t dwStatus, bool bDrawFocus) { if (bDrawFocus) return CFX_RectF(); @@ -31,7 +35,7 @@ CFX_RectF CXFA_FFDateTimeEdit::GetBBox(uint32_t dwStatus, bool bDrawFocus) { } bool CXFA_FFDateTimeEdit::PtInActiveRect(const CFX_PointF& point) { - auto* pPicker = static_cast(m_pNormalWidget.get()); + CFWL_DateTimePicker* pPicker = GetPickerWidget(); return pPicker && pPicker->GetBBox().Contains(point); } @@ -73,9 +77,8 @@ bool CXFA_FFDateTimeEdit::LoadWidget() { } void CXFA_FFDateTimeEdit::UpdateWidgetProperty() { - CFWL_DateTimePicker* pWidget = - static_cast(m_pNormalWidget.get()); - if (!pWidget) + CFWL_DateTimePicker* pPicker = GetPickerWidget(); + if (!pPicker) return; uint32_t dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat; @@ -87,14 +90,14 @@ void CXFA_FFDateTimeEdit::UpdateWidgetProperty() { Optional numCells = m_pNode->GetNumberOfCells(); if (numCells && *numCells > 0) { dwEditStyles |= FWL_STYLEEXT_EDT_CombText; - pWidget->SetEditLimit(*numCells); + pPicker->SetEditLimit(*numCells); } if (!m_pNode->IsOpenAccess() || !GetDoc()->GetXFADoc()->IsInteractive()) dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly; if (!m_pNode->IsHorizontalScrollPolicyOff()) dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll; - pWidget->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF); + pPicker->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF); } uint32_t CXFA_FFDateTimeEdit::GetAlignment() { @@ -136,7 +139,7 @@ uint32_t CXFA_FFDateTimeEdit::GetAlignment() { } bool CXFA_FFDateTimeEdit::CommitData() { - auto* pPicker = static_cast(m_pNormalWidget.get()); + CFWL_DateTimePicker* pPicker = GetPickerWidget(); if (!m_pNode->SetValue(XFA_VALUEPICTURE_Edit, pPicker->GetEditText())) return false; @@ -153,14 +156,14 @@ bool CXFA_FFDateTimeEdit::UpdateFWLData() { eType = XFA_VALUEPICTURE_Edit; WideString wsText = m_pNode->GetValue(eType); - auto* normalWidget = static_cast(m_pNormalWidget.get()); - normalWidget->SetEditText(wsText); + CFWL_DateTimePicker* pPicker = GetPickerWidget(); + pPicker->SetEditText(wsText); if (IsFocused() && !wsText.IsEmpty()) { CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pNode.Get()); CFX_DateTime date = lcValue.GetDate(); if (lcValue.IsValid()) { if (date.IsSet()) - normalWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay()); + pPicker->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay()); } } m_pNormalWidget->Update(); @@ -171,8 +174,7 @@ bool CXFA_FFDateTimeEdit::IsDataChanged() { if (m_dwStatus & XFA_WidgetStatus_TextEditValueChanged) return true; - WideString wsText = - static_cast(m_pNormalWidget.get())->GetEditText(); + WideString wsText = GetPickerWidget()->GetEditText(); return m_pNode->GetValue(XFA_VALUEPICTURE_Edit) != wsText; } @@ -189,9 +191,9 @@ void CXFA_FFDateTimeEdit::OnSelectChanged(CFWL_Widget* pWidget, date.FormatPatterns(wsDate, wsPicture, m_pNode->GetLocale(), XFA_VALUEPICTURE_Edit); - auto* pDateTime = static_cast(m_pNormalWidget.get()); - pDateTime->SetEditText(wsDate); - pDateTime->Update(); + CFWL_DateTimePicker* pPicker = GetPickerWidget(); + pPicker->SetEditText(wsDate); + pPicker->Update(); GetDoc()->GetDocEnvironment()->SetFocusWidget(GetDoc(), nullptr); CXFA_EventParam eParam; @@ -210,3 +212,65 @@ void CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event* pEvent) { } CXFA_FFTextEdit::OnProcessEvent(pEvent); } + +bool CXFA_FFDateTimeEdit::CanUndo() { + return GetPickerWidget()->CanUndo(); +} + +bool CXFA_FFDateTimeEdit::CanRedo() { + return GetPickerWidget()->CanRedo(); +} + +bool CXFA_FFDateTimeEdit::Undo() { + return GetPickerWidget()->Undo(); +} + +bool CXFA_FFDateTimeEdit::Redo() { + return GetPickerWidget()->Redo(); +} + +bool CXFA_FFDateTimeEdit::CanCopy() { + return GetPickerWidget()->HasSelection(); +} + +bool CXFA_FFDateTimeEdit::CanCut() { + if (GetPickerWidget()->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) + return false; + return GetPickerWidget()->HasSelection(); +} + +bool CXFA_FFDateTimeEdit::CanPaste() { + return !(GetPickerWidget()->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly); +} + +bool CXFA_FFDateTimeEdit::CanSelectAll() { + return GetPickerWidget()->GetEditTextLength() > 0; +} + +Optional CXFA_FFDateTimeEdit::Copy() { + return GetPickerWidget()->Copy(); +} + +Optional CXFA_FFDateTimeEdit::Cut() { + return GetPickerWidget()->Cut(); +} + +bool CXFA_FFDateTimeEdit::Paste(const WideString& wsPaste) { + return GetPickerWidget()->Paste(wsPaste); +} + +void CXFA_FFDateTimeEdit::SelectAll() { + GetPickerWidget()->SelectAll(); +} + +void CXFA_FFDateTimeEdit::Delete() { + GetPickerWidget()->ClearText(); +} + +void CXFA_FFDateTimeEdit::DeSelect() { + GetPickerWidget()->ClearSelection(); +} + +WideString CXFA_FFDateTimeEdit::GetText() { + return GetPickerWidget()->GetEditText(); +} diff --git a/xfa/fxfa/cxfa_ffdatetimeedit.h b/xfa/fxfa/cxfa_ffdatetimeedit.h index a549cbb80f..8041b313de 100644 --- a/xfa/fxfa/cxfa_ffdatetimeedit.h +++ b/xfa/fxfa/cxfa_ffdatetimeedit.h @@ -16,6 +16,7 @@ enum XFA_DATETIMETYPE { XFA_DATETIMETYPE_DateAndTime }; +class CFWL_DateTimePicker; class CFWL_Event; class CFWL_Widget; @@ -35,12 +36,31 @@ class CXFA_FFDateTimeEdit : public CXFA_FFTextEdit { int32_t iMonth, int32_t iDay); + // CXFA_FFWidget + bool CanUndo() override; + bool CanRedo() override; + bool Undo() override; + bool Redo() override; + bool CanCopy() override; + bool CanCut() override; + bool CanPaste() override; + bool CanSelectAll() override; + Optional Copy() override; + Optional Cut() override; + bool Paste(const WideString& wsPaste) override; + void SelectAll() override; + void Delete() override; + void DeSelect() override; + WideString GetText() override; + private: bool PtInActiveRect(const CFX_PointF& point) override; bool CommitData() override; bool UpdateFWLData() override; bool IsDataChanged() override; + CFWL_DateTimePicker* GetPickerWidget(); + uint32_t GetAlignment(); }; -- cgit v1.2.3