diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-02-14 19:27:28 +0100 |
---|---|---|
committer | Petr Mladek <pmladek@suse.cz> | 2013-02-19 08:56:23 +0000 |
commit | 81e283a8e5039ab7cd4d3f2ff9c520577a97ac03 (patch) | |
tree | 6dad882a9da4c065a1e7be7770a2acf664683b7b /sw | |
parent | 847371bdd92f90b74f33f226f9487d5dbff249b4 (diff) |
fdo#60732: SwTxtNode: limit to less than STRING_LEN chars
It's not a good idea to have STRING_LEN characters in a SwTxtNode
because then there is no valid SwPosition at the end of the paragraph.
Also it turns out that LO 3.6 and 4.0 do rather stupid things with a
full SwTxtNode. So enforce a limit, at first in the usual places that
are used during file import, SwTxtNode::InsertText() and
SwCntntNode::CanJoinPrev()/CanJoinNext().
Change-Id: Icb0f44acd20aa81635d42b84d4ae0f9b693a661c
(cherry picked from commit 549c0f785d4b6d4bc1b39b22827d77d66f48430a)
Reviewed-on: https://gerrit.libreoffice.org/2179
Reviewed-by: Petr Mladek <pmladek@suse.cz>
Tested-by: Petr Mladek <pmladek@suse.cz>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/ndtxt.hxx | 5 | ||||
-rw-r--r-- | sw/source/core/docnode/node.cxx | 36 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 6 |
3 files changed, 34 insertions, 13 deletions
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx index 2b0d8cdb91b6..0865fa33d059 100644 --- a/sw/inc/ndtxt.hxx +++ b/sw/inc/ndtxt.hxx @@ -70,6 +70,11 @@ namespace com { namespace sun { namespace star { typedef std::set< xub_StrLen > SwSoftPageBreakList; +// do not fill the String up to the max - need to be able to have a +// SwPosition "behind" the last character, i.e., at index TXTNODE_MAX + 1 +// (also STRING_LEN is often used for "not found") +const xub_StrLen TXTNODE_MAX = STRING_LEN - 2; + /// SwTxtNode is a paragraph in the document model. class SW_DLLPUBLIC SwTxtNode: public SwCntntNode, public ::sfx2::Metadatable { diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx index 132282fa175f..b1b19d32a209 100644 --- a/sw/source/core/docnode/node.cxx +++ b/sw/source/core/docnode/node.cxx @@ -1623,12 +1623,26 @@ const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich, return pFnd; } +static bool lcl_CheckMaxLength(SwNode const& rPrev, SwNode const& rNext) +{ + if (rPrev.GetNodeType() != rNext.GetNodeType()) + { + return false; + } + if (!rPrev.IsTxtNode()) + { + return true; + } + size_t const nSum( static_cast<const SwTxtNode&>(rPrev).GetTxt().Len() + + static_cast<const SwTxtNode&>(rNext).GetTxt().Len()); + return (nSum <= TXTNODE_MAX); +} + // Can we join two Nodes? // We can return the 2nd position in pIdx. int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const { const SwNodes& rNds = GetNodes(); - sal_uInt8 nNdType = GetNodeType(); SwNodeIndex aIdx( *this, 1 ); const SwNode* pNd = this; @@ -1637,16 +1651,11 @@ int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ))) ++aIdx; - if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() ) + if (rNds.Count()-1 == aIdx.GetIndex()) return sal_False; - if( IsTxtNode() ) - { // Do not merge strings if the result exceeds the allowed string length - const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this); - sal_uInt64 nSum = pTxtNd->GetTxt().Len(); - pTxtNd = static_cast<const SwTxtNode*>(pNd); - nSum += pTxtNd->GetTxt().Len(); - if( nSum > STRING_LEN ) - return sal_False; + if (!lcl_CheckMaxLength(*this, *pNd)) + { + return false; } if( pIdx ) *pIdx = aIdx; @@ -1657,7 +1666,6 @@ int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const // We can return the 2nd position in pIdx. int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const { - sal_uInt8 nNdType = GetNodeType(); SwNodeIndex aIdx( *this, -1 ); const SwNode* pNd = this; @@ -1666,8 +1674,12 @@ int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ))) aIdx--; - if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() ) + if (0 == aIdx.GetIndex()) return sal_False; + if (!lcl_CheckMaxLength(*pNd, *this)) + { + return false; + } if( pIdx ) *pIdx = aIdx; return sal_True; diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index eb2dd25ce948..f634571a2fdc 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -1713,7 +1713,11 @@ void SwTxtNode::InsertText( const XubString & rStr, const SwIndex & rIdx, xub_StrLen aPos = rIdx.GetIndex(); xub_StrLen nLen = m_Text.Len() - aPos; - m_Text.Insert( rStr, aPos ); + ssize_t const nOverflow(static_cast<ssize_t>(m_Text.Len()) + + static_cast<ssize_t>(rStr.Len()) - TXTNODE_MAX); + m_Text.Insert((nOverflow > 0) ? rStr.Copy(0, rStr.Len() - nOverflow) : rStr, + aPos); + assert(m_Text.Len() <= TXTNODE_MAX); nLen = m_Text.Len() - aPos - nLen; if ( !nLen ) return; |