sw/qa/core/data/rtf/pass/forcepoint-96.rtf              |    8 ++++
 sw/source/core/doc/DocumentContentOperationsManager.cxx |   31 ++++++++++++++++
 2 files changed, 39 insertions(+)

New commits:
commit bbb3779534ab4eb90591268c2b26a7bc23b49de2
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Apr 1 17:16:20 2022 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon May 16 12:34:33 2022 +0200

    forcepoint#96 sw: delete fieldmarks in DelFullPara()
    
    The problem is that CorrAbs() will move any position of a fieldmark
    that's in the deleted SwTextNodes to a different node that doesn't have
    the CH_TXT_ATR_FIELD*.
    
    Then it will inevitably crash later when it can't find its chars.
    
    The other problem is that if there's only a CH_TXT_ATR_FIELDSEP in the
    deleted nodes, that fieldmark would then be missing it.
    
    Just delete fieldmarks with positions in deleted nodes, that should work
    fine for the usual cases where DelFullPara() is called.
    
    Change-Id: I8dfac9a315d74025dbe1ed5ccb95b7c9121fb569
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132379
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    (cherry picked from commit 542673c0d4c6a992113999101f2c1bf21e0c5c22)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133937
    Tested-by: Michael Stahl <michael.st...@allotropia.de>
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/core/data/rtf/pass/forcepoint-96.rtf 
b/sw/qa/core/data/rtf/pass/forcepoint-96.rtf
new file mode 100644
index 000000000000..1e5a05d4801f
--- /dev/null
+++ b/sw/qa/core/data/rtf/pass/forcepoint-96.rtf
@@ -0,0 +1,8 @@
+{\rtf1
+\clvertalt
+\chpgn
+\clvertalb
+\cell
+\pard\intbl
+\cellx279
+}
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx 
b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 45346c3f1a04..80a3a97d242f 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -2134,6 +2134,37 @@ bool DocumentContentOperationsManager::DelFullPara( 
SwPaM& rPam )
                 return false;
             }
         }
+
+        // must delete all fieldmarks before CorrAbs(), or they'll remain
+        // moved to wrong node without their CH_TXT_ATR_FIELD*
+        // (note: deleteMarks() doesn't help here, in case of partially
+        // selected fieldmarks; let's delete these as re-inserting their chars
+        // elsewhere looks difficult)
+        ::std::set<::sw::mark::IFieldmark*> fieldmarks;
+        for (SwNodeIndex i = aRg.aStart; i <= aRg.aEnd; ++i)
+        {
+            if (SwTextNode *const pTextNode = i.GetNode().GetTextNode())
+            {
+                for (sal_Int32 j = 0; j < pTextNode->GetText().getLength(); 
++j)
+                {
+                    switch (pTextNode->GetText()[j])
+                    {
+                        case CH_TXT_ATR_FIELDSTART:
+                        case CH_TXT_ATR_FIELDEND:
+                            
fieldmarks.insert(m_rDoc.getIDocumentMarkAccess()->getFieldmarkAt(SwPosition(*pTextNode,
 j)));
+                        break;
+                        case CH_TXT_ATR_FIELDSEP:
+                            
fieldmarks.insert(m_rDoc.getIDocumentMarkAccess()->getFieldmarkFor(SwPosition(*pTextNode,
 j)));
+                        break;
+                    }
+                }
+            }
+        }
+        for (auto const pFieldMark : fieldmarks)
+        {
+            m_rDoc.getIDocumentMarkAccess()->deleteMark(pFieldMark);
+        }
+
         // move bookmarks, redlines etc.
         if (aRg.aStart == aRg.aEnd) // only first CorrAbs variant handles this
         {

Reply via email to