sc/inc/column.hxx               |    2 +-
 sc/inc/global.hxx               |    3 ++-
 sc/source/core/data/column2.cxx |   21 ++++++++++++++++++++-
 sc/source/core/data/column3.cxx |    5 ++++-
 sc/source/core/data/column4.cxx |    2 +-
 sc/source/ui/undo/undoblk.cxx   |    9 ++++++++-
 6 files changed, 36 insertions(+), 6 deletions(-)

New commits:
commit 44f34c1163882c2e3086282374fee9cd55ee211f
Author: Eike Rathke <er...@redhat.com>
Date:   Thu Sep 10 15:52:21 2015 +0200

    Resolves: tdf#92995 do not delete caption objects that are held by Undo
    
    Drag&Drop Undo is a special case of ownership..
    
    Change-Id: I2fe7769c4d84efe09d432335d5d8e72d506bf7a1

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 9d073ef..978b3713 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -584,7 +584,7 @@ public:
     ScPostIt* GetCellNote( SCROW nRow );
     const ScPostIt* GetCellNote( SCROW nRow ) const;
     const ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, 
SCROW nRow ) const;
-    void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, 
SCROW nRow2 );
+    void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, 
SCROW nRow2, bool bForgetCaptionOwnership );
     bool HasCellNotes() const;
     void SetCellNote( SCROW nRow, ScPostIt* pNote);
     bool IsNotesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index 0faaab6..8312b84 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -184,10 +184,11 @@ const InsertDeleteFlags IDF_OUTLINE   = 
InsertDeleteFlags::fromInt(0x0800);   //
 const InsertDeleteFlags IDF_NOCAPTIONS  = InsertDeleteFlags::fromInt(0x0200);  
 /// Internal use only (undo etc.): do not copy/delete caption objects of cell 
notes.
 const InsertDeleteFlags IDF_ADDNOTES    = InsertDeleteFlags::fromInt(0x0400);  
 /// Internal use only (copy from clip): do not delete existing cell contents 
when pasting notes.
 const InsertDeleteFlags IDF_SPECIAL_BOOLEAN  = 
InsertDeleteFlags::fromInt(0x1000);
+const InsertDeleteFlags IDF_FORGETCAPTIONS = 
InsertDeleteFlags::fromInt(0x2000); /// Internal use only (d&d undo): do not 
delete caption objects of cell notes.
 const InsertDeleteFlags IDF_ATTRIB     = IDF_HARDATTR | IDF_STYLES;
 const InsertDeleteFlags IDF_CONTENTS   = IDF_VALUE | IDF_DATETIME | IDF_STRING 
| IDF_NOTE | IDF_FORMULA | IDF_OUTLINE;
 const InsertDeleteFlags IDF_ALL        = IDF_CONTENTS | IDF_ATTRIB | 
IDF_OBJECTS;
-const InsertDeleteFlags IDF_ALL_USED_BITS = IDF_ALL | IDF_EDITATTR | 
IDF_NOCAPTIONS | IDF_ADDNOTES | IDF_SPECIAL_BOOLEAN;
+const InsertDeleteFlags IDF_ALL_USED_BITS = IDF_ALL | IDF_EDITATTR | 
IDF_NOCAPTIONS | IDF_ADDNOTES | IDF_SPECIAL_BOOLEAN | IDF_FORGETCAPTIONS;
 
 inline InsertDeleteFlags operator~ (const InsertDeleteFlags& rhs)
 {
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 967c35e..5347082 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1816,8 +1816,27 @@ void ScColumn::SetCellNote(SCROW nRow, ScPostIt* pNote)
     maCellNotes.set(nRow, pNote);
 }
 
-void ScColumn::DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW 
nRow1, SCROW nRow2 )
+namespace {
+class ForgetCellNoteCaptionsHandler
+{
+
+public:
+    ForgetCellNoteCaptionsHandler() {}
+
+    void operator() ( size_t /*nRow*/, ScPostIt* p )
+    {
+        p->ForgetCaption();
+    }
+};
+}
+
+void ScColumn::DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW 
nRow1, SCROW nRow2, bool bForgetCaptionOwnership )
 {
+    if (bForgetCaptionOwnership)
+    {
+        ForgetCellNoteCaptionsHandler aFunc;
+        sc::ParseNote(maCellNotes.begin(), maCellNotes, nRow1, nRow2, aFunc);
+    }
     rBlockPos.miCellNotePos =
         maCellNotes.set_empty(rBlockPos.miCellNotePos, nRow1, nRow2);
 }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index d5558e5..0bcc206 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -684,7 +684,10 @@ void ScColumn::DeleteArea(
     }
 
     if (nDelFlag & IDF_NOTE)
-        DeleteCellNotes(aBlockPos, nStartRow, nEndRow);
+    {
+        bool bForgetCaptionOwnership = ((nDelFlag & IDF_FORGETCAPTIONS) != 
IDF_NONE);
+        DeleteCellNotes(aBlockPos, nStartRow, nEndRow, 
bForgetCaptionOwnership);
+    }
 
     if ( nDelFlag & IDF_EDITATTR )
     {
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 46b59c0..ac09eac 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -114,7 +114,7 @@ void ScColumn::DeleteBeforeCopyFromClip(
         }
 
         if (nDelFlag & IDF_NOTE)
-            DeleteCellNotes(aBlockPos, nRow1, nRow2);
+            DeleteCellNotes(aBlockPos, nRow1, nRow2, false);
 
         if (nDelFlag & IDF_EDITATTR)
             RemoveEditAttribs(nRow1, nRow2);
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index 1430a12..8748a7b 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -1243,7 +1243,14 @@ void ScUndoDragDrop::DoUndo( ScRange aRange )
     // do not undo objects and note captions, they are handled via drawing undo
     InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
 
-    rDoc.DeleteAreaTab( aRange, nUndoFlags );
+    // Additionally discard/forget caption ownership during deletion, as
+    // Drag&Drop is a special case in that the Undo holds captions of the
+    // transfered target range, which would get deleted and
+    // SdrGroupUndo::Undo() would attempt to access invalidated captions and
+    // crash, tdf#92995
+    InsertDeleteFlags nDelFlags = nUndoFlags | IDF_FORGETCAPTIONS;
+
+    rDoc.DeleteAreaTab( aRange, nDelFlags );
     pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc );
     if ( rDoc.HasAttrib( aRange, HASATTR_MERGED ) )
         rDoc.ExtendMerge( aRange, true );
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to