Kaydet (Commit) 471212d4 authored tarafından Michael Stahl's avatar Michael Stahl

sw: SwRedlineTable::DeleteAndDestroy() is surprisingly dangerous

At least with the randomised test, it can happen that deleting one
redline will recursively delete other redlines that are located in
the hidden content section of the redline, or at least try to and
crash because those have already been deleted before.

The callers will either delete 1 redline, or delete all of them
via DeleteAndDestroyAll(), so put a safer loop into
DeleteAndDestroyAll() and have DeleteAndDestroy() only delete 1.

Change-Id: I9c4225544a43a4a03f4eb7b6f56e7fe848c8ca54
üst 12a841e1
...@@ -345,7 +345,7 @@ public: ...@@ -345,7 +345,7 @@ public:
void Remove( size_type nPos ); void Remove( size_type nPos );
void Remove( const SwRangeRedline* p ); void Remove( const SwRangeRedline* p );
void DeleteAndDestroy( size_type nPos, size_type nLen = 1 ); void DeleteAndDestroy(size_type nPos);
void DeleteAndDestroyAll(); void DeleteAndDestroyAll();
void dumpAsXml(struct _xmlTextWriter* pWriter) const; void dumpAsXml(struct _xmlTextWriter* pWriter) const;
...@@ -389,7 +389,7 @@ public: ...@@ -389,7 +389,7 @@ public:
void Insert( SwExtraRedline* p ); void Insert( SwExtraRedline* p );
void DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen = 1 ); void DeleteAndDestroy( sal_uInt16 nPos);
void DeleteAndDestroyAll(); void DeleteAndDestroyAll();
void dumpAsXml(struct _xmlTextWriter* pWriter) const; void dumpAsXml(struct _xmlTextWriter* pWriter) const;
......
...@@ -609,26 +609,32 @@ void SwRedlineTable::Remove( size_type nP ) ...@@ -609,26 +609,32 @@ void SwRedlineTable::Remove( size_type nP )
void SwRedlineTable::DeleteAndDestroyAll() void SwRedlineTable::DeleteAndDestroyAll()
{ {
DeleteAndDestroy(0, size()); if (maVector.empty())
} return;
SwDoc *const pDoc = maVector.front()->GetDoc();
void SwRedlineTable::DeleteAndDestroy( size_type nP, size_type nL ) while (!maVector.empty())
{ {
SwDoc* pDoc = nullptr; auto const pRedline = maVector.back();
if( !nP && nL && nL == size() ) maVector.erase(maVector.back());
pDoc = maVector.front()->GetDoc(); LOKRedlineNotification(RedlineNotification::Remove, pRedline);
delete pRedline;
for( vector_type::const_iterator it = maVector.begin() + nP; it != maVector.begin() + nP + nL; ++it ) }
if (pDoc && !pDoc->IsInDtor())
{ {
LOKRedlineNotification(RedlineNotification::Remove, *it); SwViewShell* pSh(pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() );
delete *it; if (pSh)
{
pSh->InvalidateWindows(SwRect(0, 0, SAL_MAX_INT32, SAL_MAX_INT32));
}
} }
maVector.erase( maVector.begin() + nP, maVector.begin() + nP + nL ); }
SwViewShell* pSh; void SwRedlineTable::DeleteAndDestroy(size_type const nP)
if( pDoc && !pDoc->IsInDtor() && {
nullptr != ( pSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() ) ) auto const pRedline = maVector[nP];
pSh->InvalidateWindows( SwRect( 0, 0, SAL_MAX_INT32, SAL_MAX_INT32 ) ); maVector.erase(maVector.begin() + nP);
LOKRedlineNotification(RedlineNotification::Remove, pRedline);
delete pRedline;
} }
SwRedlineTable::size_type SwRedlineTable::FindNextOfSeqNo( size_type nSttPos ) const SwRedlineTable::size_type SwRedlineTable::FindNextOfSeqNo( size_type nSttPos ) const
...@@ -1887,7 +1893,7 @@ void SwExtraRedlineTable::Insert( SwExtraRedline* p ) ...@@ -1887,7 +1893,7 @@ void SwExtraRedlineTable::Insert( SwExtraRedline* p )
//p->CallDisplayFunc(); //p->CallDisplayFunc();
} }
void SwExtraRedlineTable::DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen ) void SwExtraRedlineTable::DeleteAndDestroy(sal_uInt16 const nPos)
{ {
/* /*
SwDoc* pDoc = 0; SwDoc* pDoc = 0;
...@@ -1895,10 +1901,8 @@ void SwExtraRedlineTable::DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen ) ...@@ -1895,10 +1901,8 @@ void SwExtraRedlineTable::DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen )
pDoc = front()->GetDoc(); pDoc = front()->GetDoc();
*/ */
for( std::vector<SwExtraRedline*>::iterator it = m_aExtraRedlines.begin() + nPos; it != m_aExtraRedlines.begin() + nPos + nLen; ++it ) delete m_aExtraRedlines[nPos];
delete *it; m_aExtraRedlines.erase(m_aExtraRedlines.begin() + nPos);
m_aExtraRedlines.erase( m_aExtraRedlines.begin() + nPos, m_aExtraRedlines.begin() + nPos + nLen );
/* /*
SwViewShell* pSh; SwViewShell* pSh;
...@@ -1910,7 +1914,12 @@ void SwExtraRedlineTable::DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen ) ...@@ -1910,7 +1914,12 @@ void SwExtraRedlineTable::DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen )
void SwExtraRedlineTable::DeleteAndDestroyAll() void SwExtraRedlineTable::DeleteAndDestroyAll()
{ {
DeleteAndDestroy(0, m_aExtraRedlines.size()); while (!m_aExtraRedlines.empty())
{
auto const pRedline = m_aExtraRedlines.back();
m_aExtraRedlines.pop_back();
delete pRedline;
}
} }
SwExtraRedline::~SwExtraRedline() SwExtraRedline::~SwExtraRedline()
......
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