diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-02-15 15:28:24 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2013-02-15 22:43:48 +0100 |
commit | b6d45f26ea5bcc848737921b59a16253eb1d8587 (patch) | |
tree | 7d13102e0577be9570fb6852225c67983e677a68 /sw | |
parent | d47218d79a2440e71efb66b2224063801ba6623b (diff) |
fdo#60732: check max size in SwTxtNode::ReplaceText
Also adjust SwUndoReplace to not assume that everything was inserted and
use the stored indexes instead in Undo.
Change-Id: I52f3aaf063c2b1bd52381bdc19e29a41a12c3847
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/ndtxt.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 26 | ||||
-rw-r--r-- | sw/source/core/undo/unins.cxx | 16 |
3 files changed, 25 insertions, 19 deletions
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx index 0c48f6409b90..fb467170c257 100644 --- a/sw/inc/ndtxt.hxx +++ b/sw/inc/ndtxt.hxx @@ -333,6 +333,8 @@ public: const SwIndex & rStart, const xub_StrLen nLen); /// replace nDelLen characters at rStart with rText + /// in case the replacement does not fit, it is partially inserted up to + /// TXTNODE_MAX void ReplaceText( const SwIndex& rStart, const xub_StrLen nDelLen, const XubString& rText ); void ReplaceTextOnly( xub_StrLen nPos, xub_StrLen nLen, const XubString& rText, diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 63a2c01f2bc3..4bc16afdbbf8 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -3322,11 +3322,23 @@ XubString SwTxtNode::GetRedlineTxt( xub_StrLen nIdx, xub_StrLen nLen, *************************************************************************/ void SwTxtNode::ReplaceText( const SwIndex& rStart, const xub_StrLen nDelLen, - const XubString& rText ) + const XubString& rStr) { OSL_ENSURE( rStart.GetIndex() < m_Text.Len() && rStart.GetIndex() + nDelLen <= m_Text.Len(), "SwTxtNode::ReplaceText: index out of bounds" ); + + ssize_t const nOverflow(static_cast<ssize_t>(m_Text.Len()) + + static_cast<ssize_t>(rStr.Len()) - nDelLen - TXTNODE_MAX); + SAL_WARN_IF(nOverflow > 0, "sw.core", + "SwTxtNode::ReplaceText: node text with insertion > TXTNODE_MAX."); + OUString const sInserted( + (nOverflow > 0) ? rStr.Copy(0, rStr.Len() - nOverflow) : rStr); + if (sInserted.isEmpty()) + { + return; + } + const xub_StrLen nStartPos = rStart.GetIndex(); xub_StrLen nEndPos = nStartPos + nDelLen; xub_StrLen nLen = nDelLen; @@ -3353,17 +3365,17 @@ void SwTxtNode::ReplaceText( const SwIndex& rStart, const xub_StrLen nDelLen, bool bOldExpFlg = IsIgnoreDontExpand(); SetIgnoreDontExpand( true ); - if( nLen && rText.Len() ) + if (nLen && sInserted.getLength()) { // dann das 1. Zeichen ersetzen den Rest loschen und einfuegen // Dadurch wird die Attributierung des 1. Zeichen expandiert! - m_Text.SetChar( nStartPos, rText.GetChar( 0 ) ); + m_Text.SetChar( nStartPos, sInserted[0] ); ++((SwIndex&)rStart); m_Text.Erase( rStart.GetIndex(), nLen - 1 ); Update( rStart, nLen - 1, true ); - XubString aTmpTxt( rText ); aTmpTxt.Erase( 0, 1 ); + XubString aTmpTxt(sInserted); aTmpTxt.Erase( 0, 1 ); m_Text.Insert( aTmpTxt, rStart.GetIndex() ); Update( rStart, aTmpTxt.Len(), false ); } @@ -3372,15 +3384,15 @@ void SwTxtNode::ReplaceText( const SwIndex& rStart, const xub_StrLen nDelLen, m_Text.Erase( nStartPos, nLen ); Update( rStart, nLen, true ); - m_Text.Insert( rText, nStartPos ); - Update( rStart, rText.Len(), false ); + m_Text.Insert( sInserted, nStartPos ); + Update( rStart, sInserted.getLength(), false ); } SetIgnoreDontExpand( bOldExpFlg ); SwDelTxt aDelHint( nStartPos, nDelLen ); NotifyClients( 0, &aDelHint ); - SwInsTxt aHint( nStartPos, rText.Len() ); + SwInsTxt aHint( nStartPos, sInserted.getLength() ); NotifyClients( 0, &aHint ); } diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx index 4a0e67f1f6a0..ac49017b8c5b 100644 --- a/sw/source/core/undo/unins.cxx +++ b/sw/source/core/undo/unins.cxx @@ -672,11 +672,7 @@ void SwUndoReplace::Impl::UndoImpl(::sw::UndoRedoContext & rContext) } SwIndex aIdx( pNd, m_nSttCnt ); - if( m_nSttNd == m_nEndNd ) - { - pNd->EraseText( aIdx, sal_uInt16( m_sIns.getLength() ) ); - } - else + // don't look at m_sIns for deletion, maybe it was not completely inserted { rPam.GetPoint()->nNode = *pNd; rPam.GetPoint()->nContent.Assign( pNd, m_nSttCnt ); @@ -783,13 +779,9 @@ void SwUndoReplace::Impl::RedoImpl(::sw::UndoRedoContext & rContext) void SwUndoReplace::Impl::SetEnd(SwPaM const& rPam) { - if( rPam.GetPoint()->nNode != rPam.GetMark()->nNode ) - { - // multiple paragraphs were inserted - const SwPosition* pEnd = rPam.End(); - m_nEndNd = m_nOffset + pEnd->nNode.GetIndex(); - m_nEndCnt = pEnd->nContent.GetIndex(); - } + const SwPosition* pEnd = rPam.End(); + m_nEndNd = m_nOffset + pEnd->nNode.GetIndex(); + m_nEndCnt = pEnd->nContent.GetIndex(); } |