summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2017-04-28 18:54:27 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-05-02 15:05:46 +0200
commit4601cae591ee83ec83d707d7b82f5d61aa979c71 (patch)
tree7a0dffb3a4d8193adda7db0dc80ee2236e29f0f6
parentb78cabc850e0a71873714c892c46c9edb25fd364 (diff)
tdf#107494 sw: fix crash in SwCallMouseEvent when deleting header
The problem is that SwCallMouseEvent::PTR.pFormat is not cleared when the format is destroyed; instead SwDoc::CallEvent() checks via SwFrameFormats::Contains() that the format is still alive, which uses dynamic_cast on the deleted format. (presumably regression from 0f98299f7aa44bbb55c1bfeddca7799f727d14b0) Change-Id: I0d155c162d75b5687b58329a2a862ad57a4eb72e (cherry picked from commit 32403675bf9d2d0380956f9a82da71593edbb53c) Reviewed-on: https://gerrit.libreoffice.org/37084 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r--sw/inc/swevent.hxx39
1 files changed, 35 insertions, 4 deletions
diff --git a/sw/inc/swevent.hxx b/sw/inc/swevent.hxx
index 567928739b1d..df4478c5de84 100644
--- a/sw/inc/swevent.hxx
+++ b/sw/inc/swevent.hxx
@@ -22,6 +22,8 @@
#include <tools/solar.h>
#include <sfx2/sfx.hrc>
+#include <calbck.hxx>
+#include <frmfmt.hxx>
#define SW_EVENT_OBJECT_SELECT ( EVENT_APP_START + 0 )
#define SW_EVENT_START_INS_GLOSSARY ( EVENT_APP_START + 1 )
@@ -68,6 +70,7 @@ enum SwCallEventObjectType
// Structure for the exchange between UI/CORE.
struct SwCallMouseEvent
+ : public SwClient
{
SwCallEventObjectType eType;
union
@@ -90,14 +93,21 @@ struct SwCallMouseEvent
: eType( EVENT_OBJECT_NONE )
{ PTR.pFormat = nullptr; PTR.IMAP.pIMapObj = nullptr; }
+ SwCallMouseEvent(SwCallMouseEvent const& rOther)
+ : SwClient(rOther.GetRegisteredInNonConst())
+ , eType(rOther.eType)
+ {
+ memcpy(&PTR, &rOther.PTR, sizeof(PTR));
+ }
+
void Set( SwCallEventObjectType eTyp, const SwFrameFormat* pFormat )
- { eType = eTyp; PTR.pFormat = pFormat; PTR.IMAP.pIMapObj = nullptr; }
+ { Clear(); eType = eTyp; PTR.pFormat = pFormat; PTR.IMAP.pIMapObj = nullptr; assert(pFormat); const_cast<SwFrameFormat*>(pFormat)->Add(this); }
void Set( const SwFrameFormat* pFormat, const IMapObject* pIMapObj )
- { eType = EVENT_OBJECT_IMAGEMAP; PTR.pFormat = pFormat; PTR.IMAP.pIMapObj = pIMapObj; }
+ { Clear(); eType = EVENT_OBJECT_IMAGEMAP; PTR.pFormat = pFormat; PTR.IMAP.pIMapObj = pIMapObj; assert(pFormat); const_cast<SwFrameFormat*>(pFormat)->Add(this); }
void Set( const SwFormatINetFormat* pINetAttr )
- { eType = EVENT_OBJECT_INETATTR; PTR.pINetAttr = pINetAttr; PTR.IMAP.pIMapObj = nullptr; }
+ { Clear(); eType = EVENT_OBJECT_INETATTR; PTR.pINetAttr = pINetAttr; PTR.IMAP.pIMapObj = nullptr; }
bool operator==( const SwCallMouseEvent& rEvent ) const
{
@@ -109,9 +119,30 @@ struct SwCallMouseEvent
{ return !( *this == rEvent ); }
void Clear()
- { eType = EVENT_OBJECT_NONE; PTR.pFormat = nullptr; PTR.IMAP.pIMapObj = nullptr; }
+ {
+ if (EVENT_OBJECT_IMAGE == eType || EVENT_OBJECT_URLITEM == eType || EVENT_OBJECT_IMAGEMAP == eType)
+ {
+ // note: pFormat is not necessarily the same as
+ // GetRegisteredIn() here; see ~SwFormat()
+ assert(PTR.pFormat);
+ GetRegisteredInNonConst()->Remove(this);
+ }
+ eType = EVENT_OBJECT_NONE; PTR.pFormat = nullptr; PTR.IMAP.pIMapObj = nullptr;
+ }
bool HasEvent() const { return EVENT_OBJECT_NONE != eType; }
+
+ virtual void Modify(SfxPoolItem const*const pOldValue, SfxPoolItem const*const pNewValue) override
+ {
+ assert(EVENT_OBJECT_IMAGE == eType || EVENT_OBJECT_URLITEM == eType || EVENT_OBJECT_IMAGEMAP == eType);
+ SwClient::Modify(pOldValue, pNewValue);
+ if (!GetRegisteredIn() ||
+ (RES_FMT_CHG == pOldValue->Which()
+ && static_cast<SwFormatChg const*>(pOldValue)->pChangedFormat == PTR.pFormat))
+ {
+ Clear();
+ }
+ }
};
#endif