[Libreoffice-commits] core.git: Branch 'libreoffice-5-3' - sw/inc

Michael Stahl mstahl at redhat.com
Tue May 2 13:06:16 UTC 2017


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

New commits:
commit 4601cae591ee83ec83d707d7b82f5d61aa979c71
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
    (cherry picked from commit 32403675bf9d2d0380956f9a82da71593edbb53c)
    Reviewed-on: https://gerrit.libreoffice.org/37084
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

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


More information about the Libreoffice-commits mailing list