[PATCH libreoffice-4-0] fdo#60732: SwTxtNode: limit to less than STRING_LEN chars
Michael Stahl (via Code Review)
gerrit at gerrit.libreoffice.org
Fri Feb 15 14:35:57 PST 2013
Hi,
I have submitted a patch for review:
https://gerrit.libreoffice.org/2179
To pull it, you can do:
git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/79/2179/1
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)
---
M sw/inc/ndtxt.hxx
M sw/source/core/docnode/node.cxx
M sw/source/core/txtnode/ndtxt.cxx
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 2b0d8cd..0865fa3 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -70,6 +70,11 @@
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 132282f..b1b19d3 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1623,12 +1623,26 @@
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 @@
( 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 @@
// 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 @@
( 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 eb2dd25..f634571 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1713,7 +1713,11 @@
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;
--
To view, visit https://gerrit.libreoffice.org/2179
To unsubscribe, visit https://gerrit.libreoffice.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icb0f44acd20aa81635d42b84d4ae0f9b693a661c
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: Michael Stahl <mstahl at redhat.com>
More information about the LibreOffice
mailing list