sw/source/core/crsr/crsrsh.cxx |   16 ++++++++++++++++
 sw/source/core/crsr/swcrsr.cxx |   14 +++++++++++---
 2 files changed, 27 insertions(+), 3 deletions(-)

New commits:
commit 92d75686181349f4b79aef413a070ab8335f97b9
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Oct 18 15:17:29 2023 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Wed Oct 18 22:22:06 2023 +0200

    sw: fix stack overflow on kde45196-1.html
    
    Previously, the shell cursor was put onto a SwGrfNode in the top left
    corner, which is invalid, but didn't crash immediately.
    
    With commit b20ca8d951e8205c8b963c6b7407f984053b4094 the cursor is
    instead put onto the first SwTextNode in the body, which happens to be
    in a table, and the entire table is hidden; this causes an infinite
    recursion in SwCursorShell::UpdateCursorPos() because
    GetModelPositionForViewPoint() no longer moves it to SwGrfNode.
    
    So try to move the cursor out of a hidden node, which requires an
    additional change in SwCursor::IsSelOvr() to allow moving from a node
    without a frame to another node without a frame.
    
    Change-Id: Ia33c7b558755f7e8b65ea3ff2c46aea20be577dd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158119
    Tested-by: Michael Stahl <michael.st...@allotropia.de>
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit fa4fe53aa775cdc50eec715f4bd88469fe5e0d32)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158048
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 84f0ba59072a..04b263cda754 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -1803,6 +1803,22 @@ void SwCursorShell::UpdateCursorPos()
         GetLayout()->GetModelPositionForViewPoint( pShellCursor->GetPoint(), 
pShellCursor->GetPtPos(),
                                      &aTmpState );
         pShellCursor->DeleteMark();
+        // kde45196-1.html: try to get to a non-hidden paragraph, there must
+        // be one in the document body
+        while (isInHiddenTextFrame(pShellCursor))
+        {
+            if (!pShellCursor->MovePara(GoNextPara, fnParaStart))
+            {
+                break;
+            }
+        }
+        while (isInHiddenTextFrame(pShellCursor))
+        {
+            if (!pShellCursor->MovePara(GoPrevPara, fnParaStart))
+            {
+                break;
+            }
+        }
     }
     auto* pDoc = GetDoc();
     if (pDoc)
diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index 4349fac21b2f..8d0246bed14f 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -331,6 +331,7 @@ bool SwCursor::IsSelOvr(SwCursorSelOverFlags const eFlags)
     if( pNd->IsContentNode() && !dynamic_cast<SwUnoCursor*>(this) )
     {
         const SwContentFrame* pFrame = static_cast<const 
SwContentNode*>(pNd)->getLayoutFrame( 
rDoc.getIDocumentLayoutAccess().GetCurrentLayout() );
+        // ^ null
         if ( (SwCursorSelOverFlags::ChangePos & eFlags)   //allowed to change 
position if it's a bad one
             && pFrame && pFrame->isFrameAreaDefinitionValid()
             && !pFrame->getFrameArea().Height()     //a bad zero height 
position
@@ -400,9 +401,16 @@ bool SwCursor::IsSelOvr(SwCursorSelOverFlags const eFlags)
 
         if( !pFrame )
         {
-            DeleteMark();
-            RestoreSavePos();
-            return true; // we need a frame
+            assert(!m_vSavePos.empty());
+            SwContentNode const*const 
pSaveNode(rNds[m_vSavePos.back().nNode]->GetContentNode());
+            // if the old position already didn't have a frame, allow moving
+            // anyway, hope the caller can handle that
+            if (pSaveNode && 
pSaveNode->getLayoutFrame(rDoc.getIDocumentLayoutAccess().GetCurrentLayout()))
+            {
+                DeleteMark();
+                RestoreSavePos();
+                return true; // we need a frame
+            }
         }
     }
 

Reply via email to