Hi,
please find my proposed fix attached, review it
and if you are a PoDoFo committer, please accept
and commit it (filename gives hint for message)
separately to to the public repository.
I have added reference counting to avoid deleting
objects which are still in the data structure.
Best regards, mabri
From: Yan Pas <yanp.b...@gmail.com>
To: podofo-users@lists.sourceforge.net
Sent: Friday, 29 April 2016, 21:25 UTC
Subject: [Podofo-users] Outline erase method causes segmentation fault
Hi!
I can't manage to get Erase method to work. I have no permission to use the bug
tracker on SF (not enough rights), so I post an e-mail here.
Here is some sample code:
PdfMemDocument doc;
const PdfMemDocument indoc1("doc1.pdf");
const PdfMemDocument indoc2("doc2.pdf");
PdfOutlines * outout = doc.GetOutlines();
outout->CreateRoot("doc1.pdf");
PdfOutlineItem* root = doc.GetOutlines()->First();
doc.InsertPages(indoc1,0,3);
root->SetDestination(PdfDestination(doc.GetPage(0)));
auto nextroot = root->Next();
if (nextroot) root->InsertChild(nextroot);
auto x = doc.GetOutlines()->First()->Next();
x->Erase();
doc1 has an outline with one item. Debugger shows that x is not NULL and seg
fault appears after x->Erase(). Is it a bug or what?
Kind regards,
Yan
___
Podofo-users mailing list
Podofo-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/podofo-usersIndex: src/doc/PdfOutlines.cpp
===
--- src/doc/PdfOutlines.cpp (revision 1716)
+++ src/doc/PdfOutlines.cpp (working copy)
@@ -48,7 +48,8 @@
PdfOutlineItem* pParentOutline, PdfVecObjects* pParent )
: PdfElement( NULL, pParent ),
m_pParentOutline( pParentOutline ), m_pPrev( NULL ), m_pNext( NULL ),
- m_pFirst( NULL ), m_pLast( NULL ), m_pDestination( NULL ), m_pAction( NULL )
+ m_pFirst( NULL ), m_pLast( NULL ), m_pDestination( NULL ), m_pAction( NULL ),
+ m_nRefCount( 0 )
{
if( pParentOutline )
this->GetObject()->GetDictionary().AddKey( "Parent", pParentOutline->GetObject()->Reference() );
@@ -61,7 +62,8 @@
PdfOutlineItem* pParentOutline, PdfVecObjects* pParent )
: PdfElement( NULL, pParent ),
m_pParentOutline( pParentOutline ), m_pPrev( NULL ), m_pNext( NULL ),
- m_pFirst( NULL ), m_pLast( NULL ), m_pDestination( NULL ), m_pAction( NULL )
+ m_pFirst( NULL ), m_pLast( NULL ), m_pDestination( NULL ), m_pAction( NULL ),
+ m_nRefCount( 0 )
{
if( pParentOutline )
this->GetObject()->GetDictionary().AddKey( "Parent", pParentOutline->GetObject()->Reference() );
@@ -72,7 +74,8 @@
PdfOutlineItem::PdfOutlineItem( PdfObject* pObject, PdfOutlineItem* pParentOutline, PdfOutlineItem* pPrevious )
: PdfElement( NULL, pObject ), m_pParentOutline( pParentOutline ), m_pPrev( pPrevious ),
- m_pNext( NULL ), m_pFirst( NULL ), m_pLast( NULL ), m_pDestination( NULL ), m_pAction( NULL )
+ m_pNext( NULL ), m_pFirst( NULL ), m_pLast( NULL ), m_pDestination( NULL ), m_pAction( NULL ),
+ m_nRefCount( 0 )
{
PdfReference first, next;
@@ -96,11 +99,13 @@
if( m_pParentOutline )
m_pParentOutline->SetLast( this );
}
+++m_nRefCount;
}
PdfOutlineItem::PdfOutlineItem( PdfVecObjects* pParent )
: PdfElement( "Outlines", pParent ), m_pParentOutline( NULL ), m_pPrev( NULL ),
- m_pNext( NULL ), m_pFirst( NULL ), m_pLast( NULL ), m_pDestination( NULL ), m_pAction( NULL )
+ m_pNext( NULL ), m_pFirst( NULL ), m_pLast( NULL ), m_pDestination( NULL ), m_pAction( NULL ),
+ m_nRefCount( 0 )
{
}
@@ -134,6 +139,7 @@
this->GetObject()->GetDictionary().AddKey( "First", m_pFirst->GetObject()->Reference() );
this->GetObject()->GetDictionary().AddKey( "Last", m_pLast->GetObject()->Reference() );
+++(pItem->m_nRefCount);
}
PdfOutlineItem* PdfOutlineItem::CreateNext ( const PdfString & sTitle, const PdfDestination & rDest )
@@ -154,6 +160,7 @@
if( m_pParentOutline && !m_pNext->Next() )
m_pParentOutline->SetLast( m_pNext );
+++(pItem->m_nRefCount);
return m_pNext;
}
@@ -175,6 +182,7 @@
if( m_pParentOutline && !m_pNext->Next() )
m_pParentOutline->SetLast( m_pNext );
+++(pItem->m_nRefCount);
return m_pNext;
}
@@ -217,9 +225,13 @@
m_pFirst->Erase();
}
-if( m_pPrev && m_pNext )
+if( m_pPrev )
{
-m_pPrev->SetNext( m_pNext );
+m_pPrev->SetNext( m_pNext );
+}
+
+if( m_pNext )
+{
m_pNext->SetPrevious( m_pPrev );
}
@@ -230,7 +242,9 @@
m_pP