summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-08-25 10:48:12 +0100
committerDavid Tardon <dtardon@redhat.com>2015-08-26 13:52:56 +0000
commit36d1c0420143e71ecc5533e414339144d98fa007 (patch)
tree859948bb150c284bd149f483e2b92fd279a00fe2
parente98939c292297dd4569d8ebad0a8245d7e6f4bb6 (diff)
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 (cherry picked from commit cc596d8d0f2f896d000833ffcba0035e3812c657) Reviewed-on: https://gerrit.libreoffice.org/17983 Reviewed-by: David Tardon <dtardon@redhat.com> Tested-by: David Tardon <dtardon@redhat.com>
-rw-r--r--sw/qa/core/data/ww5/pass/crash-3.docbin0 -> 3938 bytes
-rw-r--r--sw/source/filter/ww8/ww8graf.cxx69
-rw-r--r--sw/source/filter/ww8/ww8par.hxx1
3 files changed, 59 insertions, 11 deletions
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 000000000000..54931a28206d
--- /dev/null
+++ b/sw/qa/core/data/ww5/pass/crash-3.doc
Binary files differ
diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index 77e971299158..6a0c2bba0704 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 9808af9bf365..c8f803207e6b 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1580,7 +1580,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);