sw/source/filter/basflt/fltshell.cxx | 24 +++++++++++++++++++----- sw/source/filter/inc/fltshell.hxx | 4 +++- sw/source/filter/ww8/ww8par.cxx | 2 +- 3 files changed, 23 insertions(+), 7 deletions(-)
New commits: commit 4b4ebb15456af443347679a7e7e8726c090a5bf5 Author: Michael Stahl <mst...@redhat.com> Date: Wed Aug 30 22:47:09 2017 +0200 sw: WW8 import: properly handle consecutive range annotations moz1187869-1.doc crashes on export to ODF because an annotation mark has been inserted that does not have a SwPostItField. In fact, the SwPostItField exists, but the annotation mark is at the wrong position. There are 2 consecutive range annotations in the file, so when Read_And() calls MoveAttrs(), the end of the both annotations are moved 2 times, hence later SwFltControlStack::SetAttrInDoc() will insert 2 annotation marks with the same end position, and the 2nd one will overwrite the name that the 1st one set on the 2nd SwPostItField, while the 1st SwPostItField remains with an empty name. Ensure that the end of an annotation mark is no longer moved once it's on the position of the field inserted in Read_And(). Crash is a regression from 31c54fa7bb03768b425ae019096e0a0e26e9c736. Change-Id: I0fd661e22e51701de67227f9145a13c62b10143e diff --git a/sw/source/filter/basflt/fltshell.cxx b/sw/source/filter/basflt/fltshell.cxx index 105db2d5dca7..d0df613b7033 100644 --- a/sw/source/filter/basflt/fltshell.cxx +++ b/sw/source/filter/basflt/fltshell.cxx @@ -103,6 +103,7 @@ SwFltStackEntry::SwFltStackEntry(const SwPosition& rStartPos, SfxPoolItem* pHt) : m_aMkPos(rStartPos) , m_aPtPos(rStartPos) , pAttr( pHt ) // store a copy of the attribute + , m_isAnnotationOnEnd(false) , mnStartCP(-1) , mnEndCP(-1) , bIsParaEnd(false) @@ -206,7 +207,7 @@ SwFltControlStack::~SwFltControlStack() // After setting the attribute in the doc, MoveAttrs() needs to be // called in order to push all attribute positions to the right in the // same paragraph further out by one character. -void SwFltControlStack::MoveAttrs( const SwPosition& rPos ) +void SwFltControlStack::MoveAttrs(const SwPosition& rPos, MoveAttrsMode eMode) { size_t nCnt = m_Entries.size(); sal_uLong nPosNd = rPos.nNode.GetIndex(); @@ -230,10 +231,22 @@ void SwFltControlStack::MoveAttrs( const SwPosition& rPos ) (rEntry.m_aPtPos.m_nContent >= nPosCt) ) { - rEntry.m_aPtPos.m_nContent++; - OSL_ENSURE( rEntry.m_aPtPos.m_nContent - <= pDoc->GetNodes()[nPosNd]->GetContentNode()->Len(), - "Attribute ends after end of line" ); + if ( !rEntry.m_isAnnotationOnEnd + || rEntry.m_aPtPos.m_nContent > nPosCt) + { + assert(!(rEntry.m_isAnnotationOnEnd && rEntry.m_aPtPos.m_nContent > nPosCt)); + if ( eMode == MoveAttrsMode::POSTIT_INSERTED + && rEntry.m_aPtPos.m_nContent == nPosCt + && rEntry.pAttr->Which() == RES_FLTR_ANNOTATIONMARK) + { + rEntry.m_isAnnotationOnEnd = true; + eMode = MoveAttrsMode::DEFAULT; // only set 1 flag + } + rEntry.m_aPtPos.m_nContent++; + OSL_ENSURE( rEntry.m_aPtPos.m_nContent + <= pDoc->GetNodes()[nPosNd]->GetContentNode()->Len(), + "Attribute ends after end of line" ); + } } } } @@ -646,6 +659,7 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos, dynamic_cast<SwPostItField const*>(pField->GetFormatField().GetField())); if (pPostIt) { + assert(pPostIt->GetName().isEmpty()); pDoc->getIDocumentMarkAccess()->makeAnnotationMark(aRegion, OUString()); } else diff --git a/sw/source/filter/inc/fltshell.hxx b/sw/source/filter/inc/fltshell.hxx index da282f14548f..34f1ab8862dc 100644 --- a/sw/source/filter/inc/fltshell.hxx +++ b/sw/source/filter/inc/fltshell.hxx @@ -104,6 +104,7 @@ public: bool bOld; // to mark Attributes *before* skipping field results bool bOpen; //Entry open, awaiting being closed bool bConsumedByField; + bool m_isAnnotationOnEnd; ///< annotation already moved onto its end pos. sal_Int32 mnStartCP; sal_Int32 mnEndCP; @@ -155,7 +156,8 @@ protected: bool HasSdOD(); public: - void MoveAttrs( const SwPosition& rPos ); + enum class MoveAttrsMode { DEFAULT, POSTIT_INSERTED }; + void MoveAttrs(const SwPosition& rPos, MoveAttrsMode = MoveAttrsMode::DEFAULT); enum Flags { HYPO, diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 1d68e88d301f..ca10f1b6d45b 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -2143,7 +2143,7 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes) m_rDoc.getIDocumentContentOperations().InsertPoolItem(aEnd, SwFormatField(aPostIt)); m_xCtrlStck->SetAttr(*aEnd.GetPoint(), RES_CHRATR_HIDDEN); // If this is a range, make sure that it ends after the just inserted character, not before it. - m_xReffedStck->MoveAttrs(*aEnd.GetPoint()); + m_xReffedStck->MoveAttrs(*aEnd.GetPoint(), SwFltControlStack::MoveAttrsMode::POSTIT_INSERTED); return 0; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits