From 8fa82794ffc2763e9fa1fc9d401c8e9a14d7c67f Mon Sep 17 00:00:00 2001 From: tsepez Date: Wed, 11 Jan 2017 09:32:33 -0800 Subject: Annotation deleted while retrieving it in JS Widgets as returned from GetWidgets() can pop out of existence unexpectedly, so always return observed pointers. This extends the same pattern used elsewhere in the file to all occurrences. BUG=679642 Review-Url: https://codereview.chromium.org/2624933002 --- fpdfsdk/javascript/Document.cpp | 8 ++++-- fpdfsdk/javascript/Field.cpp | 55 ++++++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 22 deletions(-) (limited to 'fpdfsdk/javascript') diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp index 29f9764806..7e4dc260f2 100644 --- a/fpdfsdk/javascript/Document.cpp +++ b/fpdfsdk/javascript/Document.cpp @@ -506,12 +506,16 @@ bool Document::removeField(IJS_Context* cc, CJS_Runtime* pRuntime = pContext->GetJSRuntime(); CFX_WideString sFieldName = params[0].ToCFXWideString(pRuntime); CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); - std::vector widgets; + std::vector widgets; pInterForm->GetWidgets(sFieldName, &widgets); if (widgets.empty()) return true; - for (CPDFSDK_Widget* pWidget : widgets) { + for (const auto& pAnnot : widgets) { + CPDFSDK_Widget* pWidget = static_cast(pAnnot.Get()); + if (!pWidget) + continue; + CFX_FloatRect rcAnnot = pWidget->GetRect(); --rcAnnot.left; --rcAnnot.bottom; diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp index f8ac479a42..e04cbd696f 100644 --- a/fpdfsdk/javascript/Field.cpp +++ b/fpdfsdk/javascript/Field.cpp @@ -265,24 +265,28 @@ void Field::UpdateFormField(CPDFSDK_FormFillEnvironment* pFormFillEnv, CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm(); if (bResetAP) { - std::vector widgets; + std::vector widgets; pInterForm->GetWidgets(pFormField, &widgets); int nFieldType = pFormField->GetFieldType(); if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_TEXTFIELD) { - for (CPDFSDK_Annot* pAnnot : widgets) { - bool bFormatted = false; - CPDFSDK_Annot::ObservedPtr pObserved(pAnnot); - CFX_WideString sValue = - static_cast(pObserved.Get())->OnFormat(bFormatted); + for (auto& pObserved : widgets) { if (pObserved) { - static_cast(pObserved.Get()) - ->ResetAppearance(bFormatted ? &sValue : nullptr, false); + bool bFormatted = false; + CFX_WideString sValue = static_cast(pObserved.Get()) + ->OnFormat(bFormatted); + if (pObserved) { // Not redundant, may be clobbered by OnFormat. + static_cast(pObserved.Get()) + ->ResetAppearance(bFormatted ? &sValue : nullptr, false); + } } } } else { - for (CPDFSDK_Widget* pWidget : widgets) { - pWidget->ResetAppearance(nullptr, false); + for (auto& pObserved : widgets) { + if (pObserved) { + static_cast(pObserved.Get()) + ->ResetAppearance(nullptr, false); + } } } } @@ -291,16 +295,18 @@ void Field::UpdateFormField(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Refresh the widget list. The calls in |bResetAP| may have caused widgets // to be removed from the list. We need to call |GetWidgets| again to be // sure none of the widgets have been deleted. - std::vector widgets; + std::vector widgets; pInterForm->GetWidgets(pFormField, &widgets); // TODO(dsinclair): Determine if all widgets share the same // CPDFSDK_InterForm. If that's the case, we can move the code to // |GetFormFillEnv| out of the loop. - for (CPDFSDK_Widget* pWidget : widgets) { - pWidget->GetInterForm() - ->GetFormFillEnv() - ->UpdateAllViews(nullptr, pWidget); + for (auto& pObserved : widgets) { + if (pObserved) { + CPDFSDK_Widget* pWidget = static_cast(pObserved.Get()); + pWidget->GetInterForm()->GetFormFillEnv()->UpdateAllViews(nullptr, + pWidget); + } } } @@ -1803,8 +1809,10 @@ bool Field::numItems(IJS_Context* cc, } bool Field::page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - if (!vp.IsGetting()) + if (!vp.IsGetting()) { + sError = JSGetStringFromID(IDS_STRING_JSREADONLY); return false; + } std::vector FieldArray = GetFormFields(m_FieldName); if (FieldArray.empty()) @@ -1814,9 +1822,8 @@ bool Field::page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { if (!pFormField) return false; - std::vector widgets; + std::vector widgets; m_pFormFillEnv->GetInterForm()->GetWidgets(pFormField, &widgets); - if (widgets.empty()) { vp << (int32_t)-1; return true; @@ -1824,13 +1831,21 @@ bool Field::page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CJS_Array PageArray; - for (size_t i = 0; i < widgets.size(); ++i) { - CPDFSDK_PageView* pPageView = widgets[i]->GetPageView(); + int i = 0; + for (const auto& pObserved : widgets) { + if (!pObserved) { + sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); + return false; + } + + auto pWidget = static_cast(pObserved.Get()); + CPDFSDK_PageView* pPageView = pWidget->GetPageView(); if (!pPageView) return false; PageArray.SetElement( pRuntime, i, CJS_Value(pRuntime, (int32_t)pPageView->GetPageIndex())); + ++i; } vp << PageArray; -- cgit v1.2.3