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 784ed64ff50bad19ab3edeefaf336a85594bddaa Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Fri Apr 1 17:16:20 2022 +0200 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Fri Apr 1 22:26: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/+/132422 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> 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 8eb9f3fc4864..a979ebddb951 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -2252,6 +2252,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 {