sw/qa/core/data/ww5/pass/crash-3.doc |binary sw/source/filter/ww8/ww8graf.cxx | 69 +++++++++++++++++++++++++++++------ sw/source/filter/ww8/ww8par.hxx | 1 3 files changed, 59 insertions(+), 11 deletions(-)
New commits: commit 0c689034cf65d5b65d32e00e2f0b0567c51df866 Author: Caolán McNamara <caol...@redhat.com> Date: Tue Aug 25 10:48:12 2015 +0100 ensure editeng str len is in sync with attributes for the duration of inserting attributes, and excess dos newline chars can be removed safely afterwards (cherry picked from commit cc596d8d0f2f896d000833ffcba0035e3812c657) Change-Id: If70e34fec1c0819f827f483d3d7ac4f19b3caef8 Reviewed-on: https://gerrit.libreoffice.org/17988 Reviewed-by: David Tardon <dtar...@redhat.com> Tested-by: David Tardon <dtar...@redhat.com> diff --git a/sw/qa/core/data/ww5/pass/crash-3.doc b/sw/qa/core/data/ww5/pass/crash-3.doc new file mode 100644 index 0000000..54931a2 Binary files /dev/null and b/sw/qa/core/data/ww5/pass/crash-3.doc differ diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx index 6562bc7..6bdbabf 100644 --- a/sw/source/filter/ww8/ww8graf.cxx +++ b/sw/source/filter/ww8/ww8graf.cxx @@ -460,23 +460,23 @@ SdrObject* SwWW8ImplReader::ReadPolyLine( WW8_DPHEAD* pHd, const WW8_DO* pDo, return pObj; } -ESelection SwWW8ImplReader::GetESelection( long nCpStart, long nCpEnd ) +ESelection GetESelection(EditEngine &rDrawEditEngine, long nCpStart, long nCpEnd) { - sal_Int32 nPCnt = mpDrawEditEngine->GetParagraphCount(); + sal_Int32 nPCnt = rDrawEditEngine.GetParagraphCount(); sal_Int32 nSP = 0; sal_Int32 nEP = 0; while( (nSP < nPCnt) - && (nCpStart >= mpDrawEditEngine->GetTextLen( nSP ) + 1) ) + && (nCpStart >= rDrawEditEngine.GetTextLen( nSP ) + 1) ) { - nCpStart -= mpDrawEditEngine->GetTextLen( nSP ) + 1; + nCpStart -= rDrawEditEngine.GetTextLen( nSP ) + 1; nSP++; } // Beim Ende erst 1 Zeichen spaeter auf naechste Zeile umschalten, // da sonst Zeilenattribute immer eine Zeile zu weit reichen. while( (nEP < nPCnt) - && (nCpEnd > mpDrawEditEngine->GetTextLen( nEP ) + 1) ) + && (nCpEnd > rDrawEditEngine.GetTextLen( nEP ) + 1) ) { - nCpEnd -= mpDrawEditEngine->GetTextLen( nEP ) + 1; + nCpEnd -= rDrawEditEngine.GetTextLen( nEP ) + 1; nEP++; } return ESelection( nSP, nCpStart, nEP, nCpEnd ); @@ -657,7 +657,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, comphelper::string::padToLength(sTemp, nTxtStart - nStartReplace, cReplaceSymbol); mpDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(), - GetESelection(nStartReplace - nStartCp, + GetESelection(*mpDrawEditEngine, nStartReplace - nStartCp, nTxtStart - nStartCp ) ); } } @@ -734,7 +734,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, if( pS->Count() ) { mpDrawEditEngine->QuickSetAttribs( *pS, - GetESelection( nTxtStart - nStartCp, nEnd - nStartCp ) ); + GetESelection(*mpDrawEditEngine, nTxtStart - nStartCp, nEnd - nStartCp) ); delete pS; pS = new SfxItemSet(mpDrawEditEngine->GetEmptyItemSet()); } @@ -752,7 +752,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, myIter aEnd = aChunks.end(); for (myIter aIter = aChunks.begin(); aIter != aEnd; ++aIter) { - ESelection aSel(GetESelection(aIter->GetStartPos()-nStartCp, + ESelection aSel(GetESelection(*mpDrawEditEngine, aIter->GetStartPos()-nStartCp, aIter->GetEndPos()-nStartCp)); OUString aString(mpDrawEditEngine->GetText(aSel)); const sal_Int32 nOrigLen = aString.getLength(); @@ -907,6 +907,47 @@ sal_Int32 SwWW8ImplReader::GetRangeAsDrawingString(OUString& rString, long nStar return 0; } +//EditEngine::InsertText will replace dos lines resulting in a shorter +//string than is passed in, so inserting attributes based on the original +//string len can fail. So here replace the dos line ends similar to +//how EditEngine does it, but preserve the length and replace the extra +//chars with placeholders, record the position of the placeholders and +//remove those extra chars after attributes have been inserted +std::vector<sal_Int32> replaceDosLineEndsButPreserveLength(OUString &rIn) +{ + OUStringBuffer aNewData(rIn); + std::vector<sal_Int32> aDosLineEndDummies; + sal_Int32 i = 0; + sal_Int32 nStrLen = rIn.getLength(); + while (i < nStrLen) + { + // \r or \n causes linebreak + if (rIn[i] == '\r' || rIn[i] == '\n') + { + // skip char if \r\n or \n\r + if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) && + (rIn[i] != rIn[i+1]) ) + { + ++i; + aDosLineEndDummies.push_back(i); + aNewData[i] = 0; + } + } + ++i; + } + rIn = aNewData.makeStringAndClear(); + return aDosLineEndDummies; +} + +void removePositions(EditEngine &rDrawEditEngine, const std::vector<sal_Int32>& rDosLineEndDummies) +{ + for (auto aIter = rDosLineEndDummies.rbegin(); aIter != rDosLineEndDummies.rend(); ++aIter) + { + sal_Int32 nCharPos(*aIter); + rDrawEditEngine.QuickDelete(GetESelection(rDrawEditEngine, nCharPos, nCharPos+1)); + } +} + OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType) { OutlinerParaObject* pRet = 0; @@ -917,8 +958,16 @@ OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP if (!mpDrawEditEngine) mpDrawEditEngine = new EditEngine(0); - mpDrawEditEngine->SetText(rString); + //replace dos line endings with editeng ones, replace any extra chars with + //placeholders to keep the inserted string len in sync with the attribute cps + //and record in aDosLineEnds the superfluous positions + OUString sEEString(rString); + std::vector<sal_Int32> aDosLineEnds(replaceDosLineEndsButPreserveLength(sEEString)); + mpDrawEditEngine->SetText(sEEString); InsertAttrsAsDrawingAttrs(nStartCp, nStartCp+nLen, eType); + //remove any superfluous placeholders of replaceDosLineEndsButPreserveLength + //after attributes have been inserted + removePositions(*mpDrawEditEngine, aDosLineEnds); // Annotations typically begin with a (useless) 0x5 if ((eType == MAN_AND) && mpDrawEditEngine->GetTextLen()) diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index 179e05f..475c70c 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -1602,7 +1602,6 @@ private: SfxAllItemSet &rSet); SdrObject *ReadPolyLine(WW8_DPHEAD* pHd, const WW8_DO* pDo, SfxAllItemSet &rSet); - ESelection GetESelection( long nCpStart, long nCpEnd ); void InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl ); void InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp, ManTypes eType, bool bONLYnPicLocFc=false);
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits