File r1924-Add-PdfRecursionGuard-to-detect-recursions-in-XRef-tables.patch of Package podofo.23799

------------------------------------------------------------------------
r1924 | domseichter | 2018-04-30 20:28:12 +0200 (lun, 30 abr 2018) | 1 line

ADDED: #7 Patch by Mark Rogers to add PdfRecursionGuard to detect recursions in XRef tables

Index: src/base/PdfParser.cpp
===================================================================
--- src/base/PdfParser.cpp	(revision 1923)
+++ src/base/PdfParser.cpp	(revision 1924)
@@ -74,6 +74,44 @@
 
 long PdfParser::s_nMaxObjects = std::numeric_limits<long>::max();
 
+class PdfRecursionGuard
+{
+  // RAII recursion guard ensures m_nRecursionDepth is always decremented
+  // because the destructor is always called when control leaves a method
+  // via return or an exception.
+  // see http://en.cppreference.com/w/cpp/language/raii
+
+  // It's used like this in PdfParser methods
+  // PdfRecursionGuard guard(m_nRecursionDepth);
+
+  public:
+    PdfRecursionGuard( int& nRecursionDepth ) 
+    : m_nRecursionDepth(nRecursionDepth) 
+    { 
+        // be careful changing this limit - overflow limits depend on the OS, linker settings, and how much stack space compiler allocates
+        // 500 limit prevents overflow on Win7 with VC++ 2005 with default linker stack size (1000 caused overflow with same compiler/OS)
+        const int maxRecursionDepth = 500;
+
+        ++m_nRecursionDepth;
+
+        if ( m_nRecursionDepth > maxRecursionDepth )
+        {
+            // avoid stack overflow on documents that have circular cross references in /Prev entries
+            // in trailer and XRef streams (possible via a chain of entries with a loop)
+            PODOFO_RAISE_ERROR( ePdfError_InvalidXRef );
+        }    
+    }
+
+    ~PdfRecursionGuard() 
+    { 
+        --m_nRecursionDepth;    
+    }
+
+  private:
+    // must be a reference so that we modify m_nRecursionDepth in parent class
+    int& m_nRecursionDepth;
+};
+
 PdfParser::PdfParser( PdfVecObjects* pVecObjects )
     : PdfTokenizer(), m_vecObjects( pVecObjects ), m_bStrictParsing( false )
 
@@ -147,7 +185,7 @@
 
     m_bIgnoreBrokenObjects = false;
     m_nIncrementalUpdates = 0;
-    m_nReadNextTrailerLevel = 0;
+    m_nRecursionDepth = 0;
 }
 
 void PdfParser::ParseFile( const char* pszFilename, bool bLoadOnDemand )
@@ -514,17 +552,7 @@
 
 void PdfParser::ReadNextTrailer()
 {
-    // be careful changing this limit - overflow limits depend on the OS, linker settings, and how much stack space compiler allocates
-    // 500 limit prevents overflow on Win7 with VC++ 2005 with default linker stack size (1000 caused overflow with same compiler/OS)
-    const int maxReadNextTrailerLevel = 500;
-    
-    ++m_nReadNextTrailerLevel;
-    
-    if ( m_nReadNextTrailerLevel > maxReadNextTrailerLevel )
-    {
-        // avoid stack overflow on documents that have circular cross references in trailer
-        PODOFO_RAISE_ERROR( ePdfError_InvalidXRef );
-    }
+    PdfRecursionGuard guard(m_nRecursionDepth);
 
     // ReadXRefcontents has read the first 't' from "trailer" so just check for "railer"
     if( this->IsNextToken( "trailer" ) )
@@ -575,8 +603,6 @@
     {
         PODOFO_RAISE_ERROR( ePdfError_NoTrailer );
     }
-
-    --m_nReadNextTrailerLevel;
 }
 
 void PdfParser::ReadTrailer()
@@ -642,6 +668,8 @@
 
 void PdfParser::ReadXRefContents( pdf_long lOffset, bool bPositionAtEnd )
 {
+    PdfRecursionGuard guard(m_nRecursionDepth);
+
     long long nFirstObject = 0;
     long long nNumObjects  = 0;
 
@@ -894,6 +922,8 @@
 
 void PdfParser::ReadXRefStreamContents( pdf_long lOffset, bool bReadOnlyTrailer )
 {
+    PdfRecursionGuard guard(m_nRecursionDepth);
+
     m_device.Device()->Seek( lOffset );
 
     PdfXRefStreamParserObject xrefObject( m_vecObjects, m_device, m_buffer, &m_offsets );
Index: src/base/PdfParser.h
===================================================================
--- src/base/PdfParser.h	(revision 1923)
+++ src/base/PdfParser.h	(revision 1924)
@@ -591,7 +591,7 @@
     bool          m_bIgnoreBrokenObjects;
 
     int           m_nIncrementalUpdates;
-    int           m_nReadNextTrailerLevel;
+    int           m_nRecursionDepth;
 
     static long   s_nMaxObjects;
 

------------------------------------------------------------------------
openSUSE Build Service is sponsored by