[Libreoffice-commits] core.git: sw/inc

Michael Stahl mstahl at redhat.com
Fri Apr 28 17:11:32 UTC 2017


 sw/inc/swevent.hxx |   39 +++++++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

New commits:
commit 32403675bf9d2d0380956f9a82da71593edbb53c
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Apr 28 18:54:27 2017 +0200

    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

diff --git a/sw/inc/swevent.hxx b/sw/inc/swevent.hxx
index ed63b5f80b39..3eb0fb8bfa23 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 )
@@ -62,6 +64,7 @@ enum SwCallEventObjectType
 // Structure for the exchange between UI/CORE.
 
 struct SwCallMouseEvent
+    : public SwClient
 {
     SwCallEventObjectType eType;
     union
@@ -84,14 +87,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
         {
@@ -103,9 +113,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


More information about the Libreoffice-commits mailing list