[Libreoffice-commits] core.git: sw/qa sw/source

Caolán McNamara caolanm at redhat.com
Tue Aug 25 03:31:39 PDT 2015


 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 cc596d8d0f2f896d000833ffcba0035e3812c657
Author: Caolán McNamara <caolanm at 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
    
    Change-Id: If70e34fec1c0819f827f483d3d7ac4f19b3caef8

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 2b66ea6..d37be70 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -443,23 +443,23 @@ SdrObject* SwWW8ImplReader::ReadPolyLine(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
     return pObj;
 }
 
-ESelection SwWW8ImplReader::GetESelection( long nCpStart, long nCpEnd )
+ESelection GetESelection(EditEngine &rDrawEditEngine, long nCpStart, long nCpEnd)
 {
-    sal_Int32 nPCnt = m_pDrawEditEngine->GetParagraphCount();
+    sal_Int32 nPCnt = rDrawEditEngine.GetParagraphCount();
     sal_Int32 nSP = 0;
     sal_Int32 nEP = 0;
     while(      (nSP < nPCnt)
-            &&  (nCpStart >= m_pDrawEditEngine->GetTextLen( nSP ) + 1) )
+            &&  (nCpStart >= rDrawEditEngine.GetTextLen( nSP ) + 1) )
     {
-        nCpStart -= m_pDrawEditEngine->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 > m_pDrawEditEngine->GetTextLen( nEP ) + 1) )
+            &&  (nCpEnd > rDrawEditEngine.GetTextLen( nEP ) + 1) )
     {
-        nCpEnd -= m_pDrawEditEngine->GetTextLen( nEP ) + 1;
+        nCpEnd -= rDrawEditEngine.GetTextLen( nEP ) + 1;
         nEP++;
     }
     return ESelection( nSP, nCpStart, nEP, nCpEnd );
@@ -641,7 +641,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
                         comphelper::string::padToLength(sTemp,
                             nTextStart - nStartReplace, cReplaceSymbol);
                         m_pDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(),
-                            GetESelection(nStartReplace - nStartCp,
+                            GetESelection(*m_pDrawEditEngine, nStartReplace - nStartCp,
                             nTextStart - nStartCp ) );
                     }
                 }
@@ -718,7 +718,7 @@ void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
             if( pS->Count() )
             {
                 m_pDrawEditEngine->QuickSetAttribs( *pS,
-                    GetESelection( nTextStart - nStartCp, nEnd - nStartCp ) );
+                    GetESelection(*m_pDrawEditEngine, nTextStart - nStartCp, nEnd - nStartCp ) );
                 delete pS;
                 pS = new SfxItemSet(m_pDrawEditEngine->GetEmptyItemSet());
             }
@@ -736,7 +736,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(*m_pDrawEditEngine, aIter->GetStartPos()-nStartCp,
             aIter->GetEndPos()-nStartCp));
         OUString aString(m_pDrawEditEngine->GetText(aSel));
         const sal_Int32 nOrigLen = aString.getLength();
@@ -891,6 +891,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;
@@ -901,8 +942,16 @@ OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP
         if (!m_pDrawEditEngine)
             m_pDrawEditEngine = new EditEngine(0);
 
-        m_pDrawEditEngine->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));
+        m_pDrawEditEngine->SetText(sEEString);
         InsertAttrsAsDrawingAttrs(nStartCp, nStartCp+nLen, eType);
+        //remove any superfluous placeholders of replaceDosLineEndsButPreserveLength
+        //after attributes have been inserted
+        removePositions(*m_pDrawEditEngine, aDosLineEnds);
 
         // Annotations typically begin with a (useless) 0x5
         if ((eType == MAN_AND) && m_pDrawEditEngine->GetTextLen())
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 400e3cc..79949ed 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1576,7 +1576,6 @@ private:
     SdrObject *ReadElipse(WW8_DPHEAD* pHd, SfxAllItemSet &rSet);
     SdrObject *ReadArc(WW8_DPHEAD* pHd, SfxAllItemSet &rSet);
     SdrObject *ReadPolyLine(WW8_DPHEAD* pHd, 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);
 


More information about the Libreoffice-commits mailing list