summaryrefslogtreecommitdiff
path: root/sw/source/core/doc/docbm.cxx
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-02-01 13:39:19 +0100
committerMichael Stahl <michael.stahl@allotropia.de>2022-02-02 09:47:23 +0100
commitea06852ee87531794f07710de496734a647a9062 (patch)
tree28d27212f238d10fbdca78142d3876ac59e75682 /sw/source/core/doc/docbm.cxx
parent4d535c4f867d86d40786788e5e5c9fd061a65673 (diff)
tdf#147008 sw_fieldmarkhide: fix invalid NonTextFieldmark positions
Commit ab6176e88f78d0b3aa2490fbc7858304c2d4a437 introduced a crash in ModelToViewHelper when the positions of a NonTextFieldmark are invalid. The NonTextFieldmark must always contain 1 CH_TXT_ATR_FORMELEMENT but after SplitNode() the position is (rr) p *pFieldMark->m_pPos1 $2 = SwPosition (node 10, offset 1) (rr) p *pFieldMark->m_pPos2 $3 = SwPosition (node 9, offset 0) This is because in ContentIdxStoreImpl::SaveBkmks() there is an asymmetry where the m_pPos2 is recorded to be wrongly corrected to node 9, but if the positions were swapped so that m_pPos1 is the start position, then it will not be recorded and remain in node 10. So fix this by changing the NonTextFieldmark to insert its CH_TXT_ATR_FORMELEMENT differently. There is some very subtle code in SwTextNode::Update() that is again asymmetric and (non-obviously) prefers to move m_pPos2 and leave m_pPos1 alone (by moving it to aTmpIdxReg) in case the positions are equal. But then the fieldmark code increments "rEnd" (which is really the m_pPos1 i.e. the start after InsertString() returns), and then decrements m_pPos2. So avoid the problem by removing these 2 pointless adjustments. Then it turns a bunch of tests fail because other code assumes that m_pPos1 is the end of the NonTextFieldmark, so fix MarkManager::changeFormFieldmarkType(), ModelToViewHelper and SwHistoryNoTextFieldmark to use GetMarkStart(). Change-Id: I7c82f9a67661121662c95727e0f8f15e06d85a3a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129289 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'sw/source/core/doc/docbm.cxx')
-rw-r--r--sw/source/core/doc/docbm.cxx8
1 files changed, 3 insertions, 5 deletions
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 5ed676719622..c15c1dd3fcea 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -1419,8 +1419,7 @@ namespace sw::mark
void MarkManager::deleteFieldmarkAt(const SwPosition& rPos)
{
auto const pFieldmark = dynamic_cast<Fieldmark*>(getFieldmarkAt(rPos));
- if (!pFieldmark)
- return;
+ assert(pFieldmark); // currently all callers require it to be there
deleteMark(lcl_FindMark(m_vAllMarks, pFieldmark));
}
@@ -1455,12 +1454,11 @@ namespace sw::mark
// Store attributes needed to create the new fieldmark
OUString sName = pFieldmark->GetName();
- SwPaM aPaM(pFieldmark->GetMarkPos());
+ SwPaM const aPaM(pFieldmark->GetMarkStart());
// Remove the old fieldmark and create a new one with the new type
- if(aPaM.GetPoint()->nContent > 0 && (rNewType == ODF_FORMDROPDOWN || rNewType == ODF_FORMCHECKBOX))
+ if (rNewType == ODF_FORMDROPDOWN || rNewType == ODF_FORMCHECKBOX)
{
- --aPaM.GetPoint()->nContent;
SwPosition aNewPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent);
deleteFieldmarkAt(aNewPos);
return makeNoTextFieldBookmark(aPaM, sName, rNewType);