[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