sw/source/core/text/itrcrsr.cxx |   58 ++++++++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 17 deletions(-)

New commits:
commit 97dcffe188f0dec4dbd0af894fe7739e1a2abcbb
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Jul 30 18:03:10 2024 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jul 31 15:41:43 2024 +0200

    tdf#162035 sw: fix crash with field in SwMultiPortion
    
    SwTextCursor::GetModelPositionForViewPoint() is recursive for
    SwMultiPortions, overriding m_pCurr via SwTextCursorSave, so the
    SwSpecialPos counting code needs to be recursive too.
    
    (regression from commit 468e5b8e0a7fefe1ca53faeb15f5f6527c37a268)
    
    Change-Id: Ic3f2f359a21dcae692400efdd693cc4042f9426e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171247
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index 6ae65945520e..0affcfcd96d1 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -1330,6 +1330,46 @@ static bool ConsiderNextPortionForCursorOffset(const 
SwLinePortion* pPor, SwTwip
     return true;
 }
 
+static auto SearchLine(SwLineLayout const*const pLineOfFoundPor,
+    SwLinePortion const*const pFoundPor,
+    int & rLines, std::vector<SwFieldPortion const*> & rPortions,
+    SwLineLayout const*const pLine) -> bool
+{
+    for (SwLinePortion const* pLP = pLine; pLP; pLP = pLP->GetNextPortion())
+    {
+        if (pLP == pFoundPor)
+        {
+            return true;
+        }
+        if (pLP->InFieldGrp())
+        {
+            SwFieldPortion const* pField(static_cast<SwFieldPortion 
const*>(pLP));
+            if (!pField->IsFollow())
+            {
+                rLines = 0;
+                rPortions.clear();
+            }
+            if (pLine == pLineOfFoundPor)
+            {
+                rPortions.emplace_back(pField);
+            }
+        }
+        else if (pLP->IsMultiPortion())
+        {
+            SwMultiPortion const*const pMulti(static_cast<SwMultiPortion 
const*>(pLP));
+            for (SwLineLayout const* pMLine = &pMulti->GetRoot();
+                    pMLine; pMLine = pMLine->GetNext())
+            {
+                if (SearchLine(pLineOfFoundPor, pFoundPor, rLines, rPortions, 
pMLine))
+                {
+                    return true;
+                }
+            }
+        }
+    }
+    return (pLine == pLineOfFoundPor);
+}
+
 // Return: Offset in String
 TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, 
const Point &rPoint,
                                     bool bChgNode, SwCursorMoveState* pCMS ) 
const
@@ -1780,23 +1820,7 @@ TextFrameIndex 
SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con
                         for (SwLineLayout const* pLine = 
GetInfo().GetParaPortion();
                                 true; pLine = pLine->GetNext())
                         {
-                            for (SwLinePortion const* pLP = pLine; pLP && pLP 
!= pPor; pLP = pLP->GetNextPortion())
-                            {
-                                if (pLP->InFieldGrp())
-                                {
-                                    SwFieldPortion const* 
pField(static_cast<SwFieldPortion const*>(pLP));
-                                    if (!pField->IsFollow())
-                                    {
-                                        nLines = 0;
-                                        portions.clear();
-                                    }
-                                    if (pLine == m_pCurr)
-                                    {
-                                        portions.emplace_back(pField);
-                                    }
-                                }
-                            }
-                            if (pLine == m_pCurr)
+                            if (SearchLine(m_pCurr, pPor, nLines, portions, 
pLine))
                             {
                                 break;
                             }

Reply via email to