summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2013-02-14 19:27:28 +0100
committerMiklos Vajna <vmiklos@suse.cz>2013-02-18 11:15:56 +0000
commit6972ce2673c9a1ad0de1a09c4ecf4fd036c59826 (patch)
tree01cfe937450de1057c670808bf0fbd934f3df0ef
parent963f9d31675706ac46a71687f6e6d561ba147c9d (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(). (cherry picked from commit 549c0f785d4b6d4bc1b39b22827d77d66f48430a) Conflicts: sw/source/core/docnode/node.cxx Change-Id: Icb0f44acd20aa81635d42b84d4ae0f9b693a661c Reviewed-on: https://gerrit.libreoffice.org/2178 Reviewed-by: Miklos Vajna <vmiklos@suse.cz> Tested-by: Miklos Vajna <vmiklos@suse.cz>
-rw-r--r--sw/inc/ndtxt.hxx5
-rw-r--r--sw/source/core/docnode/node.cxx40
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx6
3 files changed, 36 insertions, 15 deletions
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 83b3e2f35a4a..803f470b616b 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -79,6 +79,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 f79573203267..a3ce49ee79a7 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1684,12 +1684,26 @@ const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich,
return pFnd;
}
- // koennen 2 Nodes zusammengefasst werden ?
- // in pIdx kann die 2. Position returnt werden.
+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;
@@ -1698,16 +1712,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;
@@ -1719,7 +1728,6 @@ int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const
// in pIdx kann die 2. Position returnt werden.
int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const
{
- sal_uInt8 nNdType = GetNodeType();
SwNodeIndex aIdx( *this, -1 );
const SwNode* pNd = this;
@@ -1728,8 +1736,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 46ef84926d94..42c4d5145081 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1722,7 +1722,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;