Resolves: tdf#101309 crash on deleted SdrObject

when we're not recording undo, then SdrUndoDelObj just deletes
the argument its passed. And this code assumes that it is transferred
to the SdrUndoDelObj and it still exists.

Use the same pattern as ScPostIt::RemoveCaption for this situation

Invalid read of size 8
   at 0xB1713B6: SdrObject::GetOrdNum() const (svdobj.cxx:777)
   by 0x3C9E029C: ScDetectiveFunc::DeleteArrowsAt(short, int, bool) (detfunc.cxx:695)
   by 0x3C9E1D4C: ScDetectiveFunc::FindSuccLevel(short, int, short, int, unsigned short, unsigned short) (detfunc.cxx:1118)
   by 0x3C9E2405: ScDetectiveFunc::DeleteSucc(short, int) (detfunc.cxx:1207)
   by 0x3CF812BA: ScDocFunc::DetectiveRefresh(bool) (docfunc.cxx:480)
   by 0x3CFC9FAF: ScDocShell::DoHardRecalc(bool) (docsh4.cxx:1250)

 Address 0x50992d50 is 112 bytes inside a block of size 464 free'd
   at 0x4C2D22A: operator delete(void*) (vg_replace_malloc.c:576)
   by 0xB1D04BC: SdrPathObj::~SdrPathObj() (svdopath.cxx:1681)
   by 0xB1701F5: SdrObject::Free(SdrObject*&) (svdobj.cxx:394)
   by 0xB258666: SdrUndoObjList::~SdrUndoObjList() (svdundo.cxx:720)
   by 0xB258A39: SdrUndoRemoveObj::~SdrUndoRemoveObj() (svdundo.cxx:774)
   by 0xB25E29B: SdrUndoDelObj::~SdrUndoDelObj() (svdundo.hxx:298)
   by 0xB25E2B7: SdrUndoDelObj::~SdrUndoDelObj() (svdundo.hxx:298)
   by 0x3C7E5D0E: ScDrawLayer::AddCalcUndo(SdrUndoAction*) (drwlayer.cxx:1120)
   by 0x3C9E0238: ScDetectiveFunc::DeleteArrowsAt(short, int, bool) (detfunc.cxx:692)

Change-Id: Idc6d1f8e9ad8b203dac55630f8c100e74d3e017b
This commit is contained in:
Caolán McNamara
2016-08-09 21:00:59 +01:00
parent ebb9ae93c7
commit d79a4f4692
2 changed files with 14 additions and 4 deletions

View File

@@ -745,7 +745,7 @@ void ScPostIt::RemoveCaption()
{
pDrawPage->RecalcObjOrdNums();
// create drawing undo action (before removing the object to have valid draw page in undo action)
bool bRecording = ( pDrawLayer && pDrawLayer->IsRecording() );
const bool bRecording = (pDrawLayer && pDrawLayer->IsRecording());
if( bRecording )
pDrawLayer->AddCalcUndo( new SdrUndoDelObj( *maNoteData.mpCaption ) );
// remove the object from the drawing page, delete if undo is disabled

View File

@@ -688,11 +688,21 @@ void ScDetectiveFunc::DeleteArrowsAt( SCCOL nCol, SCROW nRow, bool bDestPnt )
pObject = aIter.Next();
}
for (size_t i=1; i<=nDelCount; ++i)
pModel->AddCalcUndo( new SdrUndoDelObj( *ppObj[nDelCount-i] ) );
const bool bRecording = pModel->IsRecording();
if (bRecording)
{
for (size_t i=1; i<=nDelCount; ++i)
pModel->AddCalcUndo(new SdrUndoDelObj(*ppObj[nDelCount-i]));
}
for (size_t i=1; i<=nDelCount; ++i)
pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
{
// remove the object from the drawing page, delete if undo is disabled
SdrObject* pObj = pPage->RemoveObject(ppObj[nDelCount-i]->GetOrdNum());
if( !bRecording )
SdrObject::Free( pObj );
}
ppObj.reset();