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-users
Index: 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_pParentOutline->SetLast( m_pPrev );
 
     m_pNext = NULL;
-    delete this;
+    --m_nRefCount;
+    if( m_nRefCount == 0 )
+        delete this;
 }
 
 void PdfOutlineItem::SetDestination( const PdfDestination & rDest )
Index: src/doc/PdfOutlines.h
===================================================================
--- src/doc/PdfOutlines.h	(revision 1716)
+++ src/doc/PdfOutlines.h	(working copy)
@@ -260,7 +260,9 @@
     PdfOutlineItem*    m_pLast;
 
     PdfDestination*    m_pDestination;
-    PdfAction*		   m_pAction;
+    PdfAction*         m_pAction;
+    int                m_nRefCount; // Erase() deletes only last result of 
+                       // InsertChild() remaining, otherwise only ptr changes
 };
 
 // -----------------------------------------------------
------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
_______________________________________________
Podofo-users mailing list
Podofo-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to