sw/source/core/docnode/node.cxx |   25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

New commits:
commit 447b2c6b52a29f091da7b6403ee82e796b64acc2
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Tue Mar 3 17:19:52 2020 +0100
Commit:     Michael Stahl <michael.st...@cib.de>
CommitDate: Wed Mar 4 18:26:48 2020 +0100

    tdf#130680 sw_redlinehide: fix crash in SwUndoDelete
    
    The problem is that the code that adjusts pLastNode in
    SwContentNode::DelFrames() assumes that the nodes are deleted forward
    but MoveNode() runs backward so the only solution is to put pLastNode
    temporarily onto some node without checking if it has been fully
    deleted, while skipping over tables and sections.
    
    At the end of MoveNode() it must be on a valid (not fully deleted) node
    again.
    
    (regression from b86ff2c6a88aa41379e74f11e8ec8497ff85ffd0)
    
    Change-Id: If54c01f885e0c040aed9068823deae7dd167fd50
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89896
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>
    (cherry picked from commit 4769f431d93139eb3c470e5bb4e7c3c33d46a41f)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89910
    Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de>
    (cherry picked from commit 2ef34d0272fca823ca5d5e795343e8a8ebced583)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89920
    Tested-by: Michael Stahl <michael.st...@cib.de>

diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index 14a35ef6ebc8..56986583b9d5 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1370,15 +1370,26 @@ void SwContentNode::DelFrames(SwRootFrame const*const 
pLayout)
                             *static_cast<SwTextNode*>(this), 0, Len());
                     // pointer should have been updated to a different node
                     assert(this != pMerged->pParaPropsNode);
+                    assert(GetIndex() <= pMerged->pLastNode->GetIndex());
                     if (this == pMerged->pLastNode)
                     {
-                        pMerged->pLastNode = 
GetNodes()[GetIndex()-1]->GetTextNode();
-                        // at first glance nothing guarantees this...
-                        // but the redline must end on a text-node...
-                        // so everything before this node that isn't a text
-                        // node should have been deleted already so that
-                        // there's a text node before.
-                        assert(pMerged->pLastNode->IsTextNode());
+                        // tdf#130680 find the previous node that is a
+                        // listener of pMerged; see CheckParaRedlineMerge()
+                        for (sal_uLong i = GetIndex() - 1;
+                             this == pMerged->pLastNode; --i)
+                        {
+                            SwNode *const pNode = GetNodes()[i];
+                            if (pNode->IsTextNode())
+                            {
+                                pMerged->pLastNode = pNode->GetTextNode();
+                            }
+                            else if (SwEndNode const*const pEnd = 
pNode->GetEndNode())
+                            {
+                                SwStartNode const*const 
pStart(pEnd->StartOfSectionNode());
+                                i = pStart->GetIndex(); // skip table or 
section
+                            }
+                        }
+                        assert(pMerged->pFirstNode->GetIndex() <= 
pMerged->pLastNode->GetIndex());
                     }
                     // avoid re-parenting mess (ModifyChangedHint)
                     pMerged->listener.EndListening(this);
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to