[Libreoffice-commits] core.git: Branch 'libreoffice-4-0' - sw/inc sw/source

Michael Stahl mstahl at redhat.com
Tue Feb 19 00:56:44 PST 2013


 sw/inc/ndtxt.hxx                 |    5 +++++
 sw/source/core/docnode/node.cxx  |   36 ++++++++++++++++++++++++------------
 sw/source/core/txtnode/ndtxt.cxx |    6 +++++-
 3 files changed, 34 insertions(+), 13 deletions(-)

New commits:
commit 81e283a8e5039ab7cd4d3f2ff9c520577a97ac03
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Feb 14 19:27:28 2013 +0100

    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 at suse.cz>
    Tested-by: Petr Mladek <pmladek at suse.cz>

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 @@ 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 132282f..b1b19d3 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 eb2dd25..f634571 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;


More information about the Libreoffice-commits mailing list