sw/qa/extras/uiwriter/uiwriter2.cxx           |   53 ++++++++++++++++++++++++++
 sw/source/core/doc/DocumentRedlineManager.cxx |   20 +++------
 2 files changed, 61 insertions(+), 12 deletions(-)

New commits:
commit f83e22f535c1c9482c5d3f566d5d0283355dd98f
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Tue Apr 16 19:00:50 2019 +0200
Commit:     Michael Stahl <michael.st...@cib.de>
CommitDate: Wed Apr 17 11:28:36 2019 +0200

    tdf#109376 sw: fix redline SwUndoDelete with end pos on SwTableNode crash
    
    ... that happens when you accept a delete redline (or reject an insert
    redline) with such end pos.
    
    The problem is that first a DeleteRange() will move the anchor position
    onto the table node (because check in SwUndoSaveContent::DelContentIndex()
    is surprisingly asymmetric and so the fly not deleted by the previous
    bugfix), then DelFullPara() creates a second SwUndoDelete then deleting
    the fly crashes because its anchors was moved.
    
    The code in lcl_AcceptRedline() / lcl_RejectRedline() doesn't make much
    sense (but always was like this), if we just call DeleteFullPara() once
    instead, the problem is avoided, and we don't even have to worry about
    why DelContentIndex() is so asymmetric (is "selection direction"
    really a meaningful concept?).
    
    Reportedly this started to crash with commit
    e07feb9457f2ffb373ae69b73dda290140e4005f, previously it was just wrong.
    
    Change-Id: Ib3d4b31e0255a6f4e7b49b40f204dec168ea3006
    Reviewed-on: https://gerrit.libreoffice.org/70836
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>

diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index f58819aee41c..ba15c9001d51 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -51,6 +51,7 @@ public:
     void testTdf47471_paraStyleBackground();
     void testTdf101534();
     void testTdf54819();
+    void testTdf109376_redline();
     void testTdf109376();
     void testTdf64242_optimizeTable();
     void testTdf108687_tabstop();
@@ -82,6 +83,7 @@ public:
     CPPUNIT_TEST(testTdf47471_paraStyleBackground);
     CPPUNIT_TEST(testTdf101534);
     CPPUNIT_TEST(testTdf54819);
+    CPPUNIT_TEST(testTdf109376_redline);
     CPPUNIT_TEST(testTdf109376);
     CPPUNIT_TEST(testTdf64242_optimizeTable);
     CPPUNIT_TEST(testTdf108687_tabstop);
@@ -347,6 +349,57 @@ void SwUiWriterTest2::testTdf54819()
                          getProperty<OUString>(getParagraph(1), 
"ParaStyleName"));
 }
 
+void SwUiWriterTest2::testTdf109376_redline()
+{
+    SwDoc* pDoc = createDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell);
+    // need 2 paragraphs to get to the bMoveNds case
+    pWrtShell->Insert("foo");
+    pWrtShell->SplitNode();
+    pWrtShell->Insert("bar");
+    pWrtShell->SplitNode();
+    pWrtShell->StartOfSection(false);
+
+    // add AT_PARA fly at 1st to be deleted node
+    SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
+    anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+    SfxItemSet flySet(pDoc->GetAttrPool(),
+                      svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, 
RES_ANCHOR>{});
+    flySet.Put(anchor);
+    SwFormatFrameSize size(ATT_MIN_SIZE, 1000, 1000);
+    flySet.Put(size); // set a size, else we get 1 char per line...
+    SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, 
/*bAnchValid=*/true);
+    CPPUNIT_ASSERT(pFly != nullptr);
+
+    pWrtShell->SttEndDoc(false);
+    SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
+    const SwTable& rTable = pWrtShell->InsertTable(tableOpt, 1, 1);
+
+    pWrtShell->StartOfSection(false);
+    SwPaM pam(*pWrtShell->GetCursor()->GetPoint());
+    pam.SetMark();
+    pam.GetPoint()->nNode = *rTable.GetTableNode();
+    pam.GetPoint()->nContent.Assign(nullptr, 0);
+    pam.Exchange(); // same selection direction as in doc compare...
+
+    IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
+    rIDRA.SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert | 
RedlineFlags::ShowDelete);
+    rIDRA.AppendRedline(new SwRangeRedline(nsRedlineType_t::REDLINE_DELETE, 
pam), true);
+    // this used to assert/crash with m_pAnchoredFlys mismatch because the
+    // fly was not deleted but its anchor was moved to the SwTableNode
+    rIDRA.AcceptAllRedline(true);
+
+    CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
+    sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
+    rUndoManager.Undo();
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
+    rUndoManager.Redo();
+    CPPUNIT_ASSERT_EQUAL(size_t(0), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
+    rUndoManager.Undo();
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM));
+}
+
 void SwUiWriterTest2::testTdf109376()
 {
     SwDoc* pDoc = createDoc();
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index b5431a0a79e7..47d52d6226c4 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -423,17 +423,15 @@ namespace
 
                     if( pCSttNd && pCEndNd )
                         rDoc.getIDocumentContentOperations().DeleteAndJoin( 
aPam );
-                    else
-                    {
-                        rDoc.getIDocumentContentOperations().DeleteRange( aPam 
);
-
-                        if( pCSttNd && !pCEndNd )
+                    else if (pCSttNd && !pCEndNd)
                         {
                             aPam.GetBound().nContent.Assign( nullptr, 0 );
                             aPam.GetBound( false ).nContent.Assign( nullptr, 0 
);
-                            aPam.DeleteMark();
                             rDoc.getIDocumentContentOperations().DelFullPara( 
aPam );
                         }
+                    else
+                    {
+                        rDoc.getIDocumentContentOperations().DeleteRange(aPam);
                     }
                     rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( 
eOld );
                 }
@@ -537,17 +535,15 @@ namespace
 
                     if( pCSttNd && pCEndNd )
                         rDoc.getIDocumentContentOperations().DeleteAndJoin( 
aPam );
-                    else
-                    {
-                        rDoc.getIDocumentContentOperations().DeleteRange( aPam 
);
-
-                        if( pCSttNd && !pCEndNd )
+                    else if (pCSttNd && !pCEndNd)
                         {
                             aPam.GetBound().nContent.Assign( nullptr, 0 );
                             aPam.GetBound( false ).nContent.Assign( nullptr, 0 
);
-                            aPam.DeleteMark();
                             rDoc.getIDocumentContentOperations().DelFullPara( 
aPam );
                         }
+                    else
+                    {
+                        rDoc.getIDocumentContentOperations().DeleteRange(aPam);
                     }
                     rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( 
eOld );
                 }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to