sw/inc/SwNumberTree.hxx            |   14 +++++++-------
 sw/inc/doc.hxx                     |    2 +-
 sw/inc/list.hxx                    |    2 ++
 sw/source/core/doc/list.cxx        |   19 +++++++++++++++++++
 sw/source/core/doc/poolfmt.cxx     |    9 ++++++++-
 sw/source/filter/writer/writer.cxx |   10 ++++++++--
 sw/source/filter/ww8/rtfexport.cxx |    2 +-
 sw/source/filter/ww8/wrtw8num.cxx  |    4 +++-
 sw/source/uibase/app/docstyle.cxx  |    6 +++---
 9 files changed, 52 insertions(+), 16 deletions(-)

New commits:
commit cd1c9f5167e797807d6726219f06190657f58372
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Jan 13 11:03:17 2021 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Jan 15 11:11:47 2021 +0100

    tdf#135014 sw: fix crash exporting numbering to DOCX
    
    It can happen that the default SwNumRule of a SwList isn't used by
    anything directly, but there are other SwNumRule associated with that
    SwList and then the DOCX export needs to export it as an abstract
    numbering definition.
    
    (regression from 632ee9aae6d5f3cf08b6d6b2789310c20db713b7)
    
    Change-Id: I6b1851980464aaa95bf731a60b7d11ab91cec7b6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109303
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/inc/SwNumberTree.hxx b/sw/inc/SwNumberTree.hxx
index b4625ab80138..ad45fae21910 100644
--- a/sw/inc/SwNumberTree.hxx
+++ b/sw/inc/SwNumberTree.hxx
@@ -327,6 +327,13 @@ public:
     void IsSane(bool bRecursive) const;
 #endif // DBG_UTIL
 
+    /**
+       Returns how many children this node has got.
+
+       @return number of children
+     */
+    tSwNumberTreeChildren::size_type GetChildCount() const;
+
 protected:
     /** the children */
     tSwNumberTreeChildren mChildren;
@@ -348,13 +355,6 @@ protected:
      */
     virtual bool IsNotificationEnabled() const = 0;
 
-    /**
-       Returns how many children this node has got.
-
-       @return number of children
-     */
-    tSwNumberTreeChildren::size_type GetChildCount() const;
-
     // #i64010# - made pure virtual
     virtual bool HasCountedChildren() const = 0;
 
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 3183b97f125f..987f660960c2 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -855,7 +855,7 @@ public:
     bool IsUsed( const sw::BroadcastingModify& ) const;
     /// Query if table style is used.
     bool IsUsed( const SwTableAutoFormat& ) const;
-    static bool IsUsed( const SwNumRule& );
+    bool IsUsed( const SwNumRule& );
 
     // Set name of newly loaded document template.
     size_t SetDocPattern(const OUString& rPatternName);
diff --git a/sw/inc/list.hxx b/sw/inc/list.hxx
index d8b3e16943ea..64d62faa9c93 100644
--- a/sw/inc/list.hxx
+++ b/sw/inc/list.hxx
@@ -58,6 +58,8 @@ class SwList
 
         bool IsListLevelMarked( const int nListLevel ) const;
 
+        bool HasNodes() const;
+
     private:
         SwList( const SwList& ) = delete;
         SwList& operator=( const SwList& ) = delete;
diff --git a/sw/source/core/doc/list.cxx b/sw/source/core/doc/list.cxx
index a87570131e27..7cfd1f10305f 100644
--- a/sw/source/core/doc/list.cxx
+++ b/sw/source/core/doc/list.cxx
@@ -39,6 +39,8 @@ class SwListImpl
 
         const OUString& GetDefaultListStyleName() const { return 
msDefaultListStyleName;}
 
+        bool HasNodes() const;
+
         void InsertListItem( SwNodeNum& rNodeNum, bool isHiddenRedlines,
                              const int nLevel );
         static void RemoveListItem( SwNodeNum& rNodeNum );
@@ -121,6 +123,18 @@ SwListImpl::~SwListImpl() COVERITY_NOEXCEPT_FALSE
     }
 }
 
+bool SwListImpl::HasNodes() const
+{
+    for (auto const& rNumberTree : maListTrees)
+    {
+        if (rNumberTree.pRoot->GetChildCount() != 0)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
 void SwListImpl::InsertListItem( SwNodeNum& rNodeNum, bool const 
isHiddenRedlines,
                                  const int nLevel )
 {
@@ -224,6 +238,11 @@ SwList::~SwList()
 {
 }
 
+bool SwList::HasNodes() const
+{
+    return mpListImpl->HasNodes();
+}
+
 const OUString & SwList::GetListId() const
 {
     return mpListImpl->GetListId();
diff --git a/sw/source/core/doc/poolfmt.cxx b/sw/source/core/doc/poolfmt.cxx
index c4f21573d621..d061db8735ed 100644
--- a/sw/source/core/doc/poolfmt.cxx
+++ b/sw/source/core/doc/poolfmt.cxx
@@ -25,6 +25,8 @@
 #include <doc.hxx>
 #include <IDocumentState.hxx>
 #include <IDocumentStylePoolAccess.hxx>
+#include <IDocumentListsAccess.hxx>
+#include <list.hxx>
 #include <poolfmt.hxx>
 #include <pagedesc.hxx>
 #include <fmtcol.hxx>
@@ -106,9 +108,14 @@ bool SwDoc::IsUsed( const SwTableAutoFormat& 
rTableAutoFormat) const
 // See if the NumRule is used
 bool SwDoc::IsUsed( const SwNumRule& rRule )
 {
+    SwList const*const 
pList(getIDocumentListsAccess().getListByName(rRule.GetDefaultListId()));
     bool bUsed = rRule.GetTextNodeListSize() > 0 ||
                      rRule.GetParagraphStyleListSize() > 0 ||
-                     rRule.IsUsedByRedline();
+                     rRule.IsUsedByRedline()
+            // tdf#135014 default num rule is used if any associated num rule 
is used
+            || (pList
+                && pList->GetDefaultListStyleName() == rRule.GetName()
+                && pList->HasNodes());
 
     return bUsed;
 }
diff --git a/sw/source/filter/writer/writer.cxx 
b/sw/source/filter/writer/writer.cxx
index 2311111fe39a..8076b23a5bb5 100644
--- a/sw/source/filter/writer/writer.cxx
+++ b/sw/source/filter/writer/writer.cxx
@@ -356,15 +356,18 @@ void Writer::PutNumFormatFontsInAttrPool()
     // it can be removed - it is already in the Pool
     SfxItemPool& rPool = m_pDoc->GetAttrPool();
     const SwNumRuleTable& rListTable = m_pDoc->GetNumRuleTable();
-    const SwNumRule* pRule;
     const SwNumFormat* pFormat;
     const vcl::Font* pFont;
     const vcl::Font* pDefFont = &numfunc::GetDefBulletFont();
     bool bCheck = false;
 
     for( size_t nGet = rListTable.size(); nGet; )
-        if( SwDoc::IsUsed( *(pRule = rListTable[ --nGet ] )))
+    {
+        SwNumRule const*const pRule = rListTable[ --nGet ];
+        if (m_pDoc->IsUsed(*pRule))
+        {
             for( sal_uInt8 nLvl = 0; nLvl < MAXLEVEL; ++nLvl )
+            {
                 if( SVX_NUM_CHAR_SPECIAL == (pFormat = &pRule->Get( nLvl 
))->GetNumberingType() ||
                     SVX_NUM_BITMAP == pFormat->GetNumberingType() )
                 {
@@ -384,6 +387,9 @@ void Writer::PutNumFormatFontsInAttrPool()
                                 pFont->GetFamilyName(), pFont->GetStyleName(),
                                 pFont->GetPitch(), pFont->GetCharSet(), 
RES_CHRATR_FONT ));
                 }
+            }
+        }
+    }
 }
 
 void Writer::PutEditEngFontsInAttrPool()
diff --git a/sw/source/filter/ww8/rtfexport.cxx 
b/sw/source/filter/ww8/rtfexport.cxx
index d5041849da32..7f4ceb97dd5f 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -212,7 +212,7 @@ void RtfExport::BuildNumbering()
     for (auto n = rListTable.size(); n;)
     {
         SwNumRule* pRule = rListTable[--n];
-        if (!SwDoc::IsUsed(*pRule))
+        if (!m_rDoc.IsUsed(*pRule))
             continue;
 
         if (IsExportNumRule(*pRule))
diff --git a/sw/source/filter/ww8/wrtw8num.cxx 
b/sw/source/filter/ww8/wrtw8num.cxx
index 76fad21db51e..c3f8eabe9fd9 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -91,6 +91,8 @@ sal_uInt16 MSWordExportBase::OverrideNumRule(
     const sal_uInt16 absnumdef = rListId == rAbstractRule.GetDefaultListId()
         ? GetNumberingId(rAbstractRule)
         : DuplicateAbsNum(rListId, rAbstractRule);
+    assert(numdef != USHRT_MAX);
+    assert(absnumdef != USHRT_MAX);
     auto const mapping = std::make_pair(numdef, absnumdef);
 
     auto it = m_OverridingNums.insert(std::make_pair(m_pUsedNumTable->size(), 
mapping));
@@ -120,7 +122,7 @@ sal_uInt16 MSWordExportBase::GetNumberingId( const 
SwNumRule& rNumRule )
         for ( sal_uInt16 n = m_pUsedNumTable->size(); n; )
         {
             const SwNumRule& rRule = *(*m_pUsedNumTable)[ --n ];
-            if ( !SwDoc::IsUsed( rRule ) )
+            if (!m_rDoc.IsUsed(rRule))
             {
                 m_pUsedNumTable->erase( m_pUsedNumTable->begin() + n );
             }
diff --git a/sw/source/uibase/app/docstyle.cxx 
b/sw/source/uibase/app/docstyle.cxx
index d824ac393cbd..e6eff2f4322b 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -2250,7 +2250,7 @@ bool  SwDocStyleSheet::IsUsed() const
     case SfxStyleFamily::Page : pMod = pDesc;      break;
 
     case SfxStyleFamily::Pseudo:
-            return pNumRule && SwDoc::IsUsed( *pNumRule );
+            return pNumRule && rDoc.IsUsed(*pNumRule);
 
     case SfxStyleFamily::Table:
             return pTableFormat && rDoc.IsUsed( *pTableFormat );
@@ -3015,7 +3015,7 @@ SfxStyleSheetBase*  SwStyleSheetIterator::First()
                 if ( nSrchMask == SfxStyleSearchBits::Hidden && 
!rRule.IsHidden( ) )
                     continue;
 
-                bool bUsed = bIsSearchUsed && ( bOrganizer || 
SwDoc::IsUsed(rRule) );
+                bool bUsed = bIsSearchUsed && (bOrganizer || 
rDoc.IsUsed(rRule));
                 if( !bUsed )
                 {
                     if( ( !bSearchHidden && rRule.IsHidden() ) ||
@@ -3177,7 +3177,7 @@ void SwStyleSheetIterator::AppendStyleList(const 
std::vector<OUString>& rList,
             case SwGetPoolIdFromName::NumRule:
                 {
                     SwNumRule* pRule = rDoc.FindNumRulePtr( i );
-                    bUsed = pRule && SwDoc::IsUsed( *pRule );
+                    bUsed = pRule && rDoc.IsUsed(*pRule);
                     bHidden = pRule && pRule->IsHidden( );
                 }
                 break;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to