summaryrefslogtreecommitdiff
path: root/sw
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 /sw
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>
Diffstat (limited to 'sw')
-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);