Kaydet (Commit) 05459943 authored tarafından Caolán McNamara's avatar Caolán McNamara

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: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst b380c824
......@@ -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 )
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment