summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/ndtxt.hxx5
-rw-r--r--sw/source/core/docnode/node.cxx36
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx6
3 files changed, 34 insertions, 13 deletions
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 5a47fb237883..4b78cd9731fe 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 a97261150a36..61a720f51691 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1624,12 +1624,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;
@@ -1638,16 +1652,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;
@@ -1658,7 +1667,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;
@@ -1667,8 +1675,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 aff275343862..0fa70877715e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1712,7 +1712,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;