[Libreoffice-commits] core.git: editeng/source include/editeng

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Fri Apr 26 20:19:35 UTC 2019


 editeng/source/rtf/svxrtf.cxx |   40 ++++++++++++++++++++++++++++++++++++++++
 include/editeng/svxrtf.hxx    |    5 +++--
 2 files changed, 43 insertions(+), 2 deletions(-)

New commits:
commit 05459943ce9375e6d8627b5b417c11049d26f15b
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Fri Apr 26 17:26:09 2019 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Fri Apr 26 22:18:14 2019 +0200

    ofz#13491 SvxRTFItemStackType dtor excessive recurse depth
    
    ofz#13491 SvxRTFItemStackType dtor recursively calls the dtor of its
    m_pChildList. The recurse depth can grow sufficiently to trigger asan.
    
    So breadth-first iterate through the nodes and make a flat vector of them which
    can be iterated through in order of most distant from root first and release
    their children linearly
    
    Change-Id: Icc7d7130935a27595dae7b55cea41c6a53aed956
    Reviewed-on: https://gerrit.libreoffice.org/71386
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/editeng/source/rtf/svxrtf.cxx b/editeng/source/rtf/svxrtf.cxx
index 2063ee16b728..4da3c6841263 100644
--- a/editeng/source/rtf/svxrtf.cxx
+++ b/editeng/source/rtf/svxrtf.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <memory>
+#include <queue>
 #include <tools/diagnose_ex.h>
 #include <rtl/tencinfo.h>
 #include <svl/itemiter.hxx>
@@ -857,6 +858,7 @@ void SvxRTFParser::SetAllAttrOfStk()        // end all Attr. and set it into doc
     {
         auto const& pStkSet = m_AttrSetList[--n];
         SetAttrSet( *pStkSet );
+        pStkSet->DropChildList();
         m_AttrSetList.pop_back();
     }
 }
@@ -960,6 +962,44 @@ SvxRTFItemStackType::SvxRTFItemStackType(
         aAttrSet.Put( rCpy.aAttrSet );
 }
 
+/* ofz#13491 SvxRTFItemStackType dtor recursively
+   calls the dtor of its m_pChildList. The recurse
+   depth can grow sufficiently to trigger asan.
+
+   So breadth-first iterate through the nodes
+   and make a flat vector of them which can
+   be iterated through in order of most
+   distant from root first and release
+   their children linearly
+*/
+void SvxRTFItemStackType::DropChildList()
+{
+    if (!m_pChildList || m_pChildList->empty())
+        return;
+
+    std::vector<SvxRTFItemStackType*> bfs;
+    std::queue<SvxRTFItemStackType*> aQueue;
+    aQueue.push(this);
+
+    while (!aQueue.empty())
+    {
+        auto* front = aQueue.front();
+        aQueue.pop();
+        if (front->m_pChildList)
+        {
+            for (const auto& a : *front->m_pChildList)
+                aQueue.push(a.get());
+            bfs.push_back(front);
+        }
+    }
+
+    for (auto it = bfs.rbegin(); it != bfs.rend(); ++it)
+    {
+        SvxRTFItemStackType* pNode = *it;
+        pNode->m_pChildList.reset();
+    }
+}
+
 SvxRTFItemStackType::~SvxRTFItemStackType()
 {
     if( pSttNd.get() != pEndNd )
diff --git a/include/editeng/svxrtf.hxx b/include/editeng/svxrtf.hxx
index 9d01ca41a0ff..a2de114fffaa 100644
--- a/include/editeng/svxrtf.hxx
+++ b/include/editeng/svxrtf.hxx
@@ -309,10 +309,11 @@ class EDITENG_DLLPUBLIC SvxRTFItemStackType
 
     void Add(std::unique_ptr<SvxRTFItemStackType>);
     void Compress( const SvxRTFParser& );
+    void DropChildList();
 
 public:
-    SvxRTFItemStackType( const SvxRTFItemStackType&, const EditPosition&,
-                        bool bCopyAttr );
+    SvxRTFItemStackType(const SvxRTFItemStackType&, const EditPosition&,
+                        bool bCopyAttr);
     ~SvxRTFItemStackType();
     //cmc, I'm very suspicious about SetStartPos, it doesn't change
     //its children's starting position, and the implementation looks


More information about the Libreoffice-commits mailing list