aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2019-08-23 19:04:16 +0000
committerChromium commit bot <commit-bot@chromium.org>2019-08-23 19:04:16 +0000
commit530f765067c8698e626976aa3dcf998e98371194 (patch)
tree6005fef8e798b9b8a59cc9c5ed5e1ec44d24334c
parenta775d1fcac336e82b67fbf6067bcf3c8dbe00353 (diff)
downloadpdfium-530f765067c8698e626976aa3dcf998e98371194.tar.gz
Observe FWL widgets in events/messages that destroy them.
Bug: chromium:995712 Change-Id: I3b1f8d9c31545aff4f2013cf6952791089cf65bc Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/59832 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
-rw-r--r--testing/resources/javascript/xfa_specific/bug_995712.evt3
-rw-r--r--testing/resources/javascript/xfa_specific/bug_995712.in67
-rw-r--r--testing/resources/javascript/xfa_specific/bug_995712_expected.txt0
-rw-r--r--xfa/fwl/cfwl_checkbox.cpp5
-rw-r--r--xfa/fwl/cfwl_combobox.cpp5
-rw-r--r--xfa/fwl/cfwl_datetimepicker.cpp5
-rw-r--r--xfa/fwl/cfwl_edit.cpp4
-rw-r--r--xfa/fwl/cfwl_event.h14
-rw-r--r--xfa/fwl/cfwl_eventmouse.h1
-rw-r--r--xfa/fwl/cfwl_listbox.cpp4
-rw-r--r--xfa/fwl/cfwl_message.h13
-rw-r--r--xfa/fwl/cfwl_monthcalendar.cpp4
-rw-r--r--xfa/fwl/cfwl_pushbutton.cpp6
-rw-r--r--xfa/fwl/cfwl_widget.h19
-rw-r--r--xfa/fwl/cfwl_widgetmgr.cpp1
15 files changed, 116 insertions, 35 deletions
diff --git a/testing/resources/javascript/xfa_specific/bug_995712.evt b/testing/resources/javascript/xfa_specific/bug_995712.evt
new file mode 100644
index 000000000..3a0748a19
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_995712.evt
@@ -0,0 +1,3 @@
+mousedown,left,100,100
+mouseup,left,100,100
+keycode,13
diff --git a/testing/resources/javascript/xfa_specific/bug_995712.in b/testing/resources/javascript/xfa_specific/bug_995712.in
new file mode 100644
index 000000000..c100b3731
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_995712.in
@@ -0,0 +1,67 @@
+{{header}}
+{{include ../../xfa_catalog_1_0.fragment}}
+{{include ../../xfa_object_2_0.fragment}}
+{{include ../../xfa_preamble_3_0.fragment}}
+{{include ../../xfa_config_4_0.fragment}}
+{{object 5 0}} <<
+ {{streamlen}}
+>>
+stream
+<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
+ <subform name="form1">
+ <pageSet>
+ <pageArea id="Page1" name="Page1">
+ <contentArea h="10.5in" w="8in" x="0.25in" y="0.25in"/>
+ <medium long="11in" short="8.5in" stock="letter"/>
+ </pageArea>
+ </pageSet>
+ <subform h="10.5in" w="8in" name="subform2">
+ <field h="500mm" name="pushButton0" w="500mm" x="1mm" y="1mm">
+ <ui>
+ <button/>
+ </ui>
+ <caption>
+ <value>
+ <text>ClickMe</text>
+ </value>
+ </caption>
+ <border>
+ <edge stroke="raised"/>
+ </border>
+ <event activity="mouseUp">
+ <script contentType="application/x-javascript">
+ count_mouseUp += 1;
+ if (count_mouseUp == 2) {
+ f1 = xfa.resolveNode("xfa.form..field1");
+ xfa.host.setFocus(f1);
+ xfa.template.remerge();
+ xfa.host.openList(f1);
+ }
+ </script>
+ </event>
+ </field>
+ <field h="9.0001mm" name="field1" w="47.625mm" x="6.35mm" y="92.075mm">
+ <ui>
+ <choiceList/>
+ </ui>
+ <items>
+ <text>Foo</text>
+ </items>
+ </field>
+ </subform>
+ <event activity="docReady">
+ <script contentType="application/x-javascript">
+ count_mouseUp = 0;
+ </script>
+ </event>
+ </subform>
+</template>
+endstream
+endobj
+{{include ../../xfa_locale_6_0.fragment}}
+{{include ../../xfa_postamble_7_0.fragment}}
+{{include ../../xfa_pages_8_0.fragment}}
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/javascript/xfa_specific/bug_995712_expected.txt b/testing/resources/javascript/xfa_specific/bug_995712_expected.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/resources/javascript/xfa_specific/bug_995712_expected.txt
diff --git a/xfa/fwl/cfwl_checkbox.cpp b/xfa/fwl/cfwl_checkbox.cpp
index ba8d4ae4d..f3ff43f7f 100644
--- a/xfa/fwl/cfwl_checkbox.cpp
+++ b/xfa/fwl/cfwl_checkbox.cpp
@@ -237,8 +237,9 @@ void CFWL_CheckBox::OnProcessMessage(CFWL_Message* pMessage) {
default:
break;
}
-
- CFWL_Widget::OnProcessMessage(pMessage);
+ // Dst target could be |this|, continue only if not destroyed by above.
+ if (pMessage->GetDstTarget())
+ CFWL_Widget::OnProcessMessage(pMessage);
}
void CFWL_CheckBox::OnDrawWidget(CXFA_Graphics* pGraphics,
diff --git a/xfa/fwl/cfwl_combobox.cpp b/xfa/fwl/cfwl_combobox.cpp
index 9521e2d0b..808c8c2b3 100644
--- a/xfa/fwl/cfwl_combobox.cpp
+++ b/xfa/fwl/cfwl_combobox.cpp
@@ -221,6 +221,8 @@ void CFWL_ComboBox::ShowDropList(bool bActivate) {
if (bActivate) {
CFWL_Event preEvent(CFWL_Event::Type::PreDropDown, this);
DispatchEvent(&preEvent);
+ if (!preEvent.GetSrcTarget())
+ return;
CFWL_ComboList* pComboList = m_pListBox.get();
int32_t iItems = pComboList->CountItems(nullptr);
@@ -479,7 +481,8 @@ void CFWL_ComboBox::OnProcessMessage(CFWL_Message* pMessage) {
default:
break;
}
- if (backDefault)
+ // Dst target could be |this|, continue only if not destroyed by above.
+ if (backDefault && pMessage->GetDstTarget())
CFWL_Widget::OnProcessMessage(pMessage);
}
diff --git a/xfa/fwl/cfwl_datetimepicker.cpp b/xfa/fwl/cfwl_datetimepicker.cpp
index a3fbc9cbd..b711ebaf7 100644
--- a/xfa/fwl/cfwl_datetimepicker.cpp
+++ b/xfa/fwl/cfwl_datetimepicker.cpp
@@ -378,8 +378,9 @@ void CFWL_DateTimePicker::OnProcessMessage(CFWL_Message* pMessage) {
default:
break;
}
-
- CFWL_Widget::OnProcessMessage(pMessage);
+ // Dst target could be |this|, continue only if not destroyed by above.
+ if (pMessage->GetDstTarget())
+ CFWL_Widget::OnProcessMessage(pMessage);
}
void CFWL_DateTimePicker::OnDrawWidget(CXFA_Graphics* pGraphics,
diff --git a/xfa/fwl/cfwl_edit.cpp b/xfa/fwl/cfwl_edit.cpp
index 5b70b98ec..8b70f4dd8 100644
--- a/xfa/fwl/cfwl_edit.cpp
+++ b/xfa/fwl/cfwl_edit.cpp
@@ -1039,7 +1039,9 @@ void CFWL_Edit::OnProcessMessage(CFWL_Message* pMessage) {
default:
break;
}
- CFWL_Widget::OnProcessMessage(pMessage);
+ // Dst target could be |this|, continue only if not destroyed by above.
+ if (pMessage->GetDstTarget())
+ CFWL_Widget::OnProcessMessage(pMessage);
}
void CFWL_Edit::OnProcessEvent(CFWL_Event* pEvent) {
diff --git a/xfa/fwl/cfwl_event.h b/xfa/fwl/cfwl_event.h
index 0c4d23efd..832c01f01 100644
--- a/xfa/fwl/cfwl_event.h
+++ b/xfa/fwl/cfwl_event.h
@@ -7,14 +7,8 @@
#ifndef XFA_FWL_CFWL_EVENT_H_
#define XFA_FWL_CFWL_EVENT_H_
-#include "core/fxcrt/fx_coordinates.h"
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/fx_system.h"
-#include "xfa/fwl/cfwl_messagekey.h"
-#include "xfa/fwl/cfwl_messagemouse.h"
-
-class CXFA_Graphics;
-class CFWL_Widget;
+#include "core/fxcrt/observed_ptr.h"
+#include "xfa/fwl/cfwl_widget.h"
class CFWL_Event {
public:
@@ -44,8 +38,8 @@ class CFWL_Event {
private:
const Type m_type;
- UnownedPtr<CFWL_Widget> const m_pSrcTarget;
- UnownedPtr<CFWL_Widget> const m_pDstTarget;
+ ObservedPtr<CFWL_Widget> const m_pSrcTarget;
+ ObservedPtr<CFWL_Widget> const m_pDstTarget;
};
#endif // XFA_FWL_CFWL_EVENT_H_
diff --git a/xfa/fwl/cfwl_eventmouse.h b/xfa/fwl/cfwl_eventmouse.h
index 170f39af4..273856fbc 100644
--- a/xfa/fwl/cfwl_eventmouse.h
+++ b/xfa/fwl/cfwl_eventmouse.h
@@ -8,6 +8,7 @@
#define XFA_FWL_CFWL_EVENTMOUSE_H_
#include "xfa/fwl/cfwl_event.h"
+#include "xfa/fwl/cfwl_messagemouse.h"
class CFWL_EventMouse final : public CFWL_Event {
public:
diff --git a/xfa/fwl/cfwl_listbox.cpp b/xfa/fwl/cfwl_listbox.cpp
index 8f51f5be7..4de06dbf8 100644
--- a/xfa/fwl/cfwl_listbox.cpp
+++ b/xfa/fwl/cfwl_listbox.cpp
@@ -687,7 +687,9 @@ void CFWL_ListBox::OnProcessMessage(CFWL_Message* pMessage) {
default:
break;
}
- CFWL_Widget::OnProcessMessage(pMessage);
+ // Dst target could be |this|, continue only if not destroyed by above.
+ if (pMessage->GetDstTarget())
+ CFWL_Widget::OnProcessMessage(pMessage);
}
void CFWL_ListBox::OnProcessEvent(CFWL_Event* pEvent) {
diff --git a/xfa/fwl/cfwl_message.h b/xfa/fwl/cfwl_message.h
index 2242831cc..69f7bf533 100644
--- a/xfa/fwl/cfwl_message.h
+++ b/xfa/fwl/cfwl_message.h
@@ -11,9 +11,8 @@
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/unowned_ptr.h"
-
-class CFWL_Widget;
+#include "core/fxcrt/observed_ptr.h"
+#include "xfa/fwl/cfwl_widget.h"
class CFWL_Message {
public:
@@ -24,8 +23,8 @@ class CFWL_Message {
Type GetType() const { return m_type; }
CFWL_Widget* GetSrcTarget() const { return m_pSrcTarget.Get(); }
CFWL_Widget* GetDstTarget() const { return m_pDstTarget.Get(); }
- void SetSrcTarget(CFWL_Widget* pWidget) { m_pSrcTarget = pWidget; }
- void SetDstTarget(CFWL_Widget* pWidget) { m_pDstTarget = pWidget; }
+ void SetSrcTarget(CFWL_Widget* pWidget) { m_pSrcTarget.Reset(pWidget); }
+ void SetDstTarget(CFWL_Widget* pWidget) { m_pDstTarget.Reset(pWidget); }
protected:
CFWL_Message(Type type, CFWL_Widget* pSrcTarget, CFWL_Widget* pDstTarget);
@@ -34,8 +33,8 @@ class CFWL_Message {
private:
const Type m_type;
- UnownedPtr<CFWL_Widget> m_pSrcTarget;
- UnownedPtr<CFWL_Widget> m_pDstTarget;
+ ObservedPtr<CFWL_Widget> m_pSrcTarget;
+ ObservedPtr<CFWL_Widget> m_pDstTarget;
};
#endif // XFA_FWL_CFWL_MESSAGE_H_
diff --git a/xfa/fwl/cfwl_monthcalendar.cpp b/xfa/fwl/cfwl_monthcalendar.cpp
index a856af294..76d915628 100644
--- a/xfa/fwl/cfwl_monthcalendar.cpp
+++ b/xfa/fwl/cfwl_monthcalendar.cpp
@@ -710,7 +710,9 @@ void CFWL_MonthCalendar::OnProcessMessage(CFWL_Message* pMessage) {
default:
break;
}
- CFWL_Widget::OnProcessMessage(pMessage);
+ // Dst target could be |this|, continue only if not destroyed by above.
+ if (pMessage->GetDstTarget())
+ CFWL_Widget::OnProcessMessage(pMessage);
}
void CFWL_MonthCalendar::OnDrawWidget(CXFA_Graphics* pGraphics,
diff --git a/xfa/fwl/cfwl_pushbutton.cpp b/xfa/fwl/cfwl_pushbutton.cpp
index 947b24d9a..980a89d40 100644
--- a/xfa/fwl/cfwl_pushbutton.cpp
+++ b/xfa/fwl/cfwl_pushbutton.cpp
@@ -134,7 +134,9 @@ void CFWL_PushButton::OnProcessMessage(CFWL_Message* pMessage) {
default:
break;
}
- CFWL_Widget::OnProcessMessage(pMessage);
+ // Dst target could be |this|, continue only if not destroyed by above.
+ if (pMessage->GetDstTarget())
+ CFWL_Widget::OnProcessMessage(pMessage);
}
void CFWL_PushButton::OnDrawWidget(CXFA_Graphics* pGraphics,
@@ -222,6 +224,8 @@ void CFWL_PushButton::OnKeyDown(CFWL_MessageKey* pMsg) {
CFWL_EventMouse wmMouse(this);
wmMouse.m_dwCmd = FWL_MouseCommand::LeftButtonUp;
DispatchEvent(&wmMouse);
+ if (!wmMouse.GetSrcTarget())
+ return;
CFWL_Event wmClick(CFWL_Event::Type::Click, this);
DispatchEvent(&wmClick);
diff --git a/xfa/fwl/cfwl_widget.h b/xfa/fwl/cfwl_widget.h
index 28a3aa3e9..c36cd8fa6 100644
--- a/xfa/fwl/cfwl_widget.h
+++ b/xfa/fwl/cfwl_widget.h
@@ -11,15 +11,23 @@
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/observed_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "xfa/fde/cfde_data.h"
-#include "xfa/fwl/cfwl_event.h"
#include "xfa/fwl/cfwl_themepart.h"
#include "xfa/fwl/cfwl_widgetmgr.h"
#include "xfa/fwl/cfwl_widgetproperties.h"
#include "xfa/fwl/fwl_widgethit.h"
#include "xfa/fwl/ifwl_widgetdelegate.h"
+class CFWL_App;
+class CFWL_AppImp;
+class CFWL_Event;
+class CFWL_MessageKey;
+class CFWL_Widget;
+class CFWL_WidgetMgr;
+class IFWL_ThemeProvider;
+
enum class FWL_Type {
Unknown = 0,
@@ -40,15 +48,8 @@ enum class FWL_Type {
ToolTip
};
-class CFWL_App;
-class CFWL_AppImp;
-class CFWL_MessageKey;
-class CFWL_Widget;
-class CFWL_WidgetMgr;
-class IFWL_ThemeProvider;
-
// NOTE: CFWL_Widget serves as its own delegate until replaced at runtime.
-class CFWL_Widget : public IFWL_WidgetDelegate {
+class CFWL_Widget : public Observable, public IFWL_WidgetDelegate {
public:
class AdapterIface {
public:
diff --git a/xfa/fwl/cfwl_widgetmgr.cpp b/xfa/fwl/cfwl_widgetmgr.cpp
index 1eefe37a3..cb4143096 100644
--- a/xfa/fwl/cfwl_widgetmgr.cpp
+++ b/xfa/fwl/cfwl_widgetmgr.cpp
@@ -11,6 +11,7 @@
#include "build/build_config.h"
#include "third_party/base/ptr_util.h"
#include "xfa/fwl/cfwl_app.h"
+#include "xfa/fwl/cfwl_message.h"
#include "xfa/fwl/cfwl_notedriver.h"
CFWL_WidgetMgr::CFWL_WidgetMgr(AdapterIface* pAdapterNative)