parent
417201e931
commit
293333fe96
@ -1,127 +0,0 @@
|
||||
Description: CVE-2017-5852
|
||||
The part coming from the email is not (yet?) merged, it's there only to
|
||||
prevent an ABI breakage and can be safely dropped at the next SONAME bump.
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Bug-Debian: https://bugs.debian.org/854600
|
||||
Origin: https://sourceforge.net/p/podofo/code/1838
|
||||
Origin: https://sourceforge.net/p/podofo/code/1835
|
||||
Origin: https://sourceforge.net/p/podofo/code/1841
|
||||
Origin: https://sourceforge.net/p/podofo/mailman/message/36084628/
|
||||
Last-Update: 2017-11-12
|
||||
|
||||
--- a/src/base/PdfError.cpp
|
||||
+++ b/src/base/PdfError.cpp
|
||||
@@ -222,6 +222,9 @@
|
||||
case ePdfError_InvalidEnumValue:
|
||||
pszMsg = "ePdfError_InvalidEnumValue";
|
||||
break;
|
||||
+ case ePdfError_BrokenFile:
|
||||
+ pszMsg = "ePdfError_BrokenFile";
|
||||
+ break;
|
||||
case ePdfError_PageNotFound:
|
||||
pszMsg = "ePdfError_PageNotFound";
|
||||
break;
|
||||
@@ -397,6 +400,9 @@
|
||||
case ePdfError_InvalidEnumValue:
|
||||
pszMsg = "An invalid enum value was specified.";
|
||||
break;
|
||||
+ case ePdfError_BrokenFile:
|
||||
+ pszMsg = "The file content is broken.";
|
||||
+ break;
|
||||
case ePdfError_PageNotFound:
|
||||
pszMsg = "The requested page could not be found in the PDF.";
|
||||
break;
|
||||
--- a/src/base/PdfError.h
|
||||
+++ b/src/base/PdfError.h
|
||||
@@ -73,6 +73,7 @@
|
||||
ePdfError_ValueOutOfRange, /**< The specified memory is out of the allowed range. */
|
||||
ePdfError_InternalLogic, /**< An internal sanity check or assertion failed. */
|
||||
ePdfError_InvalidEnumValue, /**< An invalid enum value was specified. */
|
||||
+ ePdfError_BrokenFile, /**< The file content is broken. */
|
||||
|
||||
ePdfError_PageNotFound, /**< The requested page could not be found in the PDF. */
|
||||
|
||||
--- a/src/doc/PdfPage.cpp
|
||||
+++ b/src/doc/PdfPage.cpp
|
||||
@@ -214,6 +214,11 @@
|
||||
|
||||
const PdfObject* PdfPage::GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject ) const
|
||||
{
|
||||
+ return GetInheritedKeyFromObject( inKey, inObject, 0);
|
||||
+}
|
||||
+
|
||||
+const PdfObject* PdfPage::GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject, int depth ) const
|
||||
+{
|
||||
const PdfObject* pObj = NULL;
|
||||
|
||||
// check for it in the object itself
|
||||
@@ -227,9 +232,29 @@
|
||||
// if we get here, we need to go check the parent - if there is one!
|
||||
if( inObject->GetDictionary().HasKey( "Parent" ) )
|
||||
{
|
||||
+ // CVE-2017-5852 - prevent stack overflow if Parent chain contains a loop, or is very long
|
||||
+ // e.g. pObj->GetParent() == pObj or pObj->GetParent()->GetParent() == pObj
|
||||
+ // default stack sizes
|
||||
+ // Windows: 1 MB
|
||||
+ // Linux: 2 MB
|
||||
+ // macOS: 8 MB for main thread, 0.5 MB for secondary threads
|
||||
+ // 0.5 MB is enough space for 1000 512 byte stack frames and 2000 256 byte stack frames
|
||||
+ const int maxRecursionDepth = 1000;
|
||||
+
|
||||
+ if ( depth > maxRecursionDepth )
|
||||
+ PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange );
|
||||
+
|
||||
pObj = inObject->GetIndirectKey( "Parent" );
|
||||
+ if( pObj == inObject )
|
||||
+ {
|
||||
+ std::ostringstream oss;
|
||||
+ oss << "Object " << inObject->Reference().ObjectNumber() << " "
|
||||
+ << inObject->Reference().GenerationNumber() << " references itself as Parent";
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_BrokenFile, oss.str().c_str() );
|
||||
+ }
|
||||
+
|
||||
if( pObj )
|
||||
- pObj = GetInheritedKeyFromObject( inKey, pObj );
|
||||
+ pObj = GetInheritedKeyFromObject( inKey, pObj, depth + 1 );
|
||||
}
|
||||
|
||||
return pObj;
|
||||
@@ -523,6 +548,11 @@
|
||||
PdfObject* pParent = this->GetObject()->GetIndirectKey( "Parent" );
|
||||
PdfReference ref = this->GetObject()->Reference();
|
||||
|
||||
+ // CVE-2017-5852 - prevent infinite loop if Parent chain contains a loop
|
||||
+ // e.g. pParent->GetIndirectKey( "Parent" ) == pParent or pParent->GetIndirectKey( "Parent" )->GetIndirectKey( "Parent" ) == pParent
|
||||
+ const int maxRecursionDepth = 1000;
|
||||
+ int depth = 0;
|
||||
+
|
||||
while( pParent )
|
||||
{
|
||||
PdfObject* pKids = pParent->GetIndirectKey( "Kids" );
|
||||
@@ -554,6 +584,12 @@
|
||||
|
||||
ref = pParent->Reference();
|
||||
pParent = pParent->GetIndirectKey( "Parent" );
|
||||
+ ++depth;
|
||||
+
|
||||
+ if ( depth > maxRecursionDepth )
|
||||
+ {
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_BrokenFile, "Loop in Parent chain" );
|
||||
+ }
|
||||
}
|
||||
|
||||
return ++nPageNumber;
|
||||
--- a/src/doc/PdfPage.h
|
||||
+++ b/src/doc/PdfPage.h
|
||||
@@ -291,7 +291,10 @@
|
||||
/** Method for getting a key value that could be inherited (such as the boxes, resources, etc.)
|
||||
* \returns PdfObject - the result of the key fetching or NULL
|
||||
*/
|
||||
- const PdfObject* GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject ) const;
|
||||
+ const PdfObject* GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject ) const; // wraps the next one
|
||||
+
|
||||
+ // this is introduced by the fix for CVE-2017-5852, the depth param counts recursion depth, is checked against a max
|
||||
+ const PdfObject* GetInheritedKeyFromObject( const char* inKey, const PdfObject* inObject, int depth ) const PODOFO_LOCAL;
|
||||
|
||||
/** Get the annotations array.
|
||||
* \param bCreate if true the annotations array is created
|
@ -1,77 +0,0 @@
|
||||
Description: CVE-2017-5853 and CVE-2017-6844
|
||||
Acked-By: Markus Koschany <apo@debian.org>
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-Update: 2017-05-03
|
||||
Bug-Debian: https://bugs.debian.org/854601
|
||||
Bug-Debian: https://bugs.debian.org/861561
|
||||
Origin: https://sourceforge.net/p/podofo/code/1840
|
||||
|
||||
--- a/src/base/PdfParser.cpp
|
||||
+++ b/src/base/PdfParser.cpp
|
||||
@@ -748,21 +748,39 @@
|
||||
|
||||
void PdfParser::ReadXRefSubsection( pdf_int64 & nFirstObject, pdf_int64 & nNumObjects )
|
||||
{
|
||||
- int count = 0;
|
||||
+ pdf_int64 count = 0;
|
||||
|
||||
#ifdef PODOFO_VERBOSE_DEBUG
|
||||
PdfError::DebugMessage("Reading XRef Section: %" PDF_FORMAT_INT64 " with %" PDF_FORMAT_INT64 " Objects.\n", nFirstObject, nNumObjects );
|
||||
#endif // PODOFO_VERBOSE_DEBUG
|
||||
|
||||
- if ( nFirstObject + nNumObjects > m_nNumObjects )
|
||||
+ if ( nFirstObject < 0 )
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange, "ReadXRefSubsection: nFirstObject is negative" );
|
||||
+ if ( nNumObjects < 0 )
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange, "ReadXRefSubsection: nNumObjects is negative" );
|
||||
+
|
||||
+ const pdf_int64 maxNum
|
||||
+ = static_cast<pdf_int64>(PdfParser::s_nMaxObjects);
|
||||
+
|
||||
+ // overflow guard, fixes CVE-2017-5853 (signed integer overflow)
|
||||
+ // also fixes CVE-2017-6844 (buffer overflow) together with below size check
|
||||
+ if( (maxNum >= nNumObjects) && (nFirstObject <= maxNum - nNumObjects) )
|
||||
{
|
||||
- // Total number of xref entries to read is greater than the /Size
|
||||
- // specified in the trailer if any. That's an error unless we're trying
|
||||
- // to recover from a missing /Size entry.
|
||||
- PdfError::LogMessage( eLogSeverity_Warning,
|
||||
- "There are more objects (%" PDF_FORMAT_INT64 ") in this XRef table than "
|
||||
- "specified in the size key of the trailer directory (%" PDF_FORMAT_INT64 ")!\n",
|
||||
- nFirstObject + nNumObjects, m_nNumObjects );
|
||||
+ if( nFirstObject + nNumObjects > m_nNumObjects )
|
||||
+ {
|
||||
+ // Total number of xref entries to read is greater than the /Size
|
||||
+ // specified in the trailer if any. That's an error unless we're
|
||||
+ // trying to recover from a missing /Size entry.
|
||||
+ PdfError::LogMessage( eLogSeverity_Warning,
|
||||
+ "There are more objects (%" PDF_FORMAT_INT64 ") in this XRef "
|
||||
+ "table than specified in the size key of the trailer directory "
|
||||
+ "(%" PDF_FORMAT_INT64 ")!\n", nFirstObject + nNumObjects,
|
||||
+ static_cast<pdf_int64>( m_nNumObjects ));
|
||||
+ }
|
||||
+
|
||||
+ if ( static_cast<pdf_uint64>( nFirstObject ) + static_cast<pdf_uint64>( nNumObjects ) > static_cast<pdf_uint64>( std::numeric_limits<size_t>::max() ) )
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange,
|
||||
+ "xref subsection's given entry numbers together too large" );
|
||||
|
||||
#ifdef _WIN32
|
||||
m_nNumObjects = static_cast<long>(nFirstObject + nNumObjects);
|
||||
@@ -771,7 +789,16 @@
|
||||
m_nNumObjects = nFirstObject + nNumObjects;
|
||||
m_offsets.resize(nFirstObject+nNumObjects);
|
||||
#endif // _WIN32
|
||||
- }
|
||||
+
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ PdfError::LogMessage( eLogSeverity_Error, "There are more objects (%" PDF_FORMAT_INT64
|
||||
+ " + %" PDF_FORMAT_INT64 " seemingly) in this XRef"
|
||||
+ " table than supported by standard PDF, or it's inconsistent.\n",
|
||||
+ nFirstObject, nNumObjects);
|
||||
+ PODOFO_RAISE_ERROR( ePdfError_InvalidXRef );
|
||||
+ }
|
||||
|
||||
// consume all whitespaces
|
||||
int charcode;
|
@ -1,20 +0,0 @@
|
||||
Description: CVE-2017-5854
|
||||
Acked-By: Markus Koschany <apo@debian.org>
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-Update: 2017-05-03
|
||||
Bug-Debian: https://bugs.debian.org/854602
|
||||
Origin: https://sourceforge.net/p/podofo/code/1836
|
||||
|
||||
--- a/tools/podofopdfinfo/pdfinfo.cpp
|
||||
+++ b/tools/podofopdfinfo/pdfinfo.cpp
|
||||
@@ -207,6 +207,10 @@
|
||||
for ( int pg=0; pg<pgCount; pg++ )
|
||||
{
|
||||
curPage = mDoc->GetPage( pg );
|
||||
+ if( !curPage )
|
||||
+ {
|
||||
+ PODOFO_RAISE_ERROR( PoDoFo::ePdfError_PageNotFound );
|
||||
+ }
|
||||
rect = curPage->GetMediaBox();
|
||||
Format s( rect.GetWidth() - rect.GetLeft(), rect.GetHeight() - rect.GetBottom());
|
||||
sIt = sizes.find(s);
|
@ -1,27 +0,0 @@
|
||||
Description: CVE-2017-5855
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-Update: 2017-05-17
|
||||
Origin: https://sourceforge.net/p/podofo/code/1843
|
||||
Bug-Debian: https://bugs.debian.org/854603
|
||||
|
||||
--- a/src/base/PdfParser.cpp
|
||||
+++ b/src/base/PdfParser.cpp
|
||||
@@ -782,6 +782,7 @@
|
||||
PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange,
|
||||
"xref subsection's given entry numbers together too large" );
|
||||
|
||||
+ try {
|
||||
#ifdef _WIN32
|
||||
m_nNumObjects = static_cast<long>(nFirstObject + nNumObjects);
|
||||
m_offsets.resize(static_cast<long>(nFirstObject+nNumObjects));
|
||||
@@ -789,7 +790,9 @@
|
||||
m_nNumObjects = nFirstObject + nNumObjects;
|
||||
m_offsets.resize(nFirstObject+nNumObjects);
|
||||
#endif // _WIN32
|
||||
-
|
||||
+ } catch (std::bad_alloc &ex) {
|
||||
+ PODOFO_RAISE_ERROR( ePdfError_OutOfMemory );
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
@ -1,18 +0,0 @@
|
||||
Description: CVE-2017-5886
|
||||
Acked-By: Markus Koschany <apo@debian.org>
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-Update: 2017-05-03
|
||||
Bug-Debian: https://bugs.debian.org/854604
|
||||
Origin: https://sourceforge.net/p/podofo/code/1837
|
||||
|
||||
--- a/src/base/PdfTokenizer.cpp
|
||||
+++ b/src/base/PdfTokenizer.cpp
|
||||
@@ -239,7 +239,7 @@
|
||||
*peType = ePdfTokenType_Token;
|
||||
|
||||
while( (c = m_device.Device()->Look()) != EOF
|
||||
- && counter < static_cast<pdf_int64>(m_buffer.GetSize()) )
|
||||
+ && counter + 1 < static_cast<pdf_int64>(m_buffer.GetSize()) )
|
||||
{
|
||||
// ignore leading whitespaces
|
||||
if( !counter && IsWhitespace( c ) )
|
@ -1,25 +0,0 @@
|
||||
Description: CVE-2017-6840 and CVE-2017-6842 and CVE-2017-6843
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-UpdatE: 2017-05-17
|
||||
Origin: https://sourceforge.net/p/podofo/code/1844
|
||||
Origin: https://sourceforge.net/p/podofo/code/1845
|
||||
Bug-Debian: https://bugs.debian.org/861557
|
||||
Bug-Debian: https://bugs.debian.org/861559
|
||||
Bug-Debian: https://bugs.debian.org/861560
|
||||
|
||||
--- a/tools/podofocolor/colorchanger.cpp
|
||||
+++ b/tools/podofocolor/colorchanger.cpp
|
||||
@@ -181,6 +181,13 @@
|
||||
int nNumArgs = pInfo->nNumArguments;
|
||||
EPdfColorSpace eColorSpace;
|
||||
|
||||
+ if( pInfo->nNumArguments > 0 && args.size() != static_cast<size_t>( pInfo->nNumArguments ) )
|
||||
+ {
|
||||
+ std::ostringstream oss;
|
||||
+ oss << "Expected " << pInfo->nNumArguments << " argument(s) for keyword '" << pszKeyword << "', but " << args.size() << " given instead.";
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidContentStream, oss.str().c_str() );
|
||||
+ }
|
||||
+
|
||||
switch( pInfo->eKeywordType )
|
||||
{
|
||||
case eKeyword_GraphicsStack_Push:
|
@ -1,27 +0,0 @@
|
||||
Description: CVE-2017-6845
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Bug-Debian: https://bugs.debian.org/861562
|
||||
Origin: https://sourceforge.net/p/podofo/code/1892
|
||||
|
||||
--- a/src/base/PdfError.h
|
||||
+++ b/src/base/PdfError.h
|
||||
@@ -167,18 +167,8 @@
|
||||
*
|
||||
* Evaluate `x' as a binary predicate and if it is true, raise a logic error with the
|
||||
* info string `y' .
|
||||
- *
|
||||
- * This macro will be undefined when NDEBUG is set, so it's compiled out for release
|
||||
- * builds. Use it for expensive or extremely frequent sanity checking.
|
||||
- *
|
||||
- * We define it then UNDEF it to help out doxygen.
|
||||
*/
|
||||
-#ifndef NDEBUG
|
||||
- // Woo for double-negatives. We define PODOFO_RAISE_LOGIC_IF unless we've been told not to by NDEBUG.
|
||||
- #define PODOFO_RAISE_LOGIC_IF( x, y ) { if (x) throw ::PoDoFo::PdfError( ePdfError_InternalLogic, __FILE__, __LINE__, y ); };
|
||||
-#else
|
||||
- #define PODOFO_RAISE_LOGIC_IF( x, y ) {};
|
||||
-#endif
|
||||
+#define PODOFO_RAISE_LOGIC_IF( x, y ) { if (x) throw ::PoDoFo::PdfError( ePdfError_InternalLogic, __FILE__, __LINE__, y ); };
|
||||
|
||||
class PODOFO_API PdfErrorInfo {
|
||||
public:
|
@ -1,21 +0,0 @@
|
||||
Description: CVE-2017-6847 and CVE-2017-6848
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-Update: 2017-05-17
|
||||
Origin: https://sourceforge.net/p/podofo/code/1846
|
||||
Bug-Debian: https://bugs.debian.org/861564
|
||||
Bug-Debian: https://bugs.debian.org/861565
|
||||
|
||||
--- a/src/doc/PdfXObject.cpp
|
||||
+++ b/src/doc/PdfXObject.cpp
|
||||
@@ -261,8 +261,10 @@
|
||||
|
||||
m_pResources = pObject->GetIndirectKey( "Resources" );
|
||||
m_Identifier = PdfName( out.str().c_str() );
|
||||
- m_rRect = PdfRect( this->GetObject()->GetIndirectKey( "BBox" )->GetArray() );
|
||||
m_Reference = this->GetObject()->Reference();
|
||||
+
|
||||
+ if( this->GetObject()->GetIndirectKey( "BBox" ) )
|
||||
+ m_rRect = PdfRect( this->GetObject()->GetIndirectKey( "BBox" )->GetArray() );
|
||||
}
|
||||
|
||||
void PdfXObject::InitXObject( const PdfRect & rRect, const char* pszPrefix )
|
@ -1,38 +0,0 @@
|
||||
Description: CVE-2017-7378
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-Update: 2017-05-17
|
||||
Origin: https://sourceforge.net/p/podofo/code/1847
|
||||
Bug-Debian: https://bugs.debian.org/859330
|
||||
|
||||
--- a/src/doc/PdfPainter.cpp
|
||||
+++ b/src/doc/PdfPainter.cpp
|
||||
@@ -1938,16 +1938,27 @@
|
||||
const pdf_utf16be cTab = 0x0900;
|
||||
const pdf_utf16be cSpace = 0x2000;
|
||||
|
||||
+ if( lStringLen == -1 )
|
||||
+ lStringLen = rsString.GetCharacterLength();
|
||||
+
|
||||
+ if (lStringLen > rsString.GetCharacterLength())
|
||||
+ {
|
||||
+ PdfError::DebugMessage( "Requested to expand tabs in string of %" PDF_FORMAT_INT64 " chars, while it has only %" PDF_FORMAT_INT64 "; correcting the value\n",
|
||||
+ static_cast<pdf_int64>( lStringLen ), static_cast<pdf_int64>( rsString.GetCharacterLength() ) );
|
||||
+
|
||||
+ lStringLen = rsString.GetCharacterLength();
|
||||
+ }
|
||||
+
|
||||
// count the number of tabs in the string
|
||||
if( bUnicode )
|
||||
{
|
||||
- for( i=0;i<=lStringLen;i++ )
|
||||
+ for( i=0;i<lStringLen;i++ )
|
||||
if( rsString.GetUnicode()[i] == cTab )
|
||||
++nTabCnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
- for( i=0;i<=lStringLen;i++ )
|
||||
+ for( i=0;i<lStringLen;i++ )
|
||||
if( rsString.GetString()[i] == '\t' )
|
||||
++nTabCnt;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
Description: CVE-2017-7379
|
||||
Acked-By: Markus Koschany <apo@debian.org>
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-Update: 2017-05-03
|
||||
Bug-Debian: https://bugs.debian.org/859331
|
||||
Origin: https://sourceforge.net/p/podofo/code/1842
|
||||
|
||||
--- a/src/base/PdfEncoding.cpp
|
||||
+++ b/src/base/PdfEncoding.cpp
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <stack>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#include <limits>
|
||||
#include <sstream>
|
||||
#include "PdfArray.h"
|
||||
#include "doc/PdfDifferenceEncoding.h"
|
||||
@@ -362,7 +363,9 @@
|
||||
void PdfSimpleEncoding::InitEncodingTable()
|
||||
{
|
||||
Util::PdfMutexWrapper wrapper( *m_mutex );
|
||||
- const long lTableLength = 0xffff;
|
||||
+ // CVE-2017-7379 - previously lTableLength was 0xffff, but pdf_utf16be characters can be in range 0..0xffff so this
|
||||
+ // caused out-by-one heap overflow when character 0xffff was encoded
|
||||
+ const long lTableLength = std::numeric_limits<pdf_utf16be>::max() + 1;
|
||||
const pdf_utf16be* cpUnicodeTable = this->GetToUnicodeTable();
|
||||
|
||||
if( !m_pEncodingTable ) // double check
|
@ -1,17 +0,0 @@
|
||||
Description: CVE-2017-7380 and CVE-2017-7381 and CVE-2017-7382 and CVE-2017-7383
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Last-Update: 2017-05-17
|
||||
Origin: https://sourceforge.net/p/podofo/code/1848
|
||||
Bug-Debian: https://bugs.debian.org/859329
|
||||
|
||||
--- a/src/doc/PdfPage.cpp
|
||||
+++ b/src/doc/PdfPage.cpp
|
||||
@@ -647,7 +647,7 @@
|
||||
// OC 15.08.2010 BugFix: Ghostscript creates here sometimes an indirect reference to a directory
|
||||
// PdfObject* pType = m_pResources->GetDictionary().GetKey( rType );
|
||||
PdfObject* pType = m_pResources->GetIndirectKey( rType );
|
||||
- if( pType->IsDictionary() && pType->GetDictionary().HasKey( rKey ) )
|
||||
+ if( pType && pType->IsDictionary() && pType->GetDictionary().HasKey( rKey ) )
|
||||
{
|
||||
const PdfReference & ref = pType->GetDictionary().GetKey( rKey )->GetReference();
|
||||
return this->GetObject()->GetOwner()->GetObject( ref );
|
@ -1,103 +0,0 @@
|
||||
Description: CVE-2017-7994
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Origin: https://sourceforge.net/p/podofo/code/1849
|
||||
Bug-Debian: https://bugs.debian.org/860930
|
||||
Last-Update: 2017-11-12
|
||||
|
||||
--- a/tools/podofotxtextract/TextExtractor.cpp
|
||||
+++ b/tools/podofotxtextract/TextExtractor.cpp
|
||||
@@ -72,10 +72,21 @@
|
||||
if( strcmp( pszToken, "l" ) == 0 ||
|
||||
strcmp( pszToken, "m" ) == 0 )
|
||||
{
|
||||
- dCurPosX = stack.top().GetReal();
|
||||
- stack.pop();
|
||||
- dCurPosY = stack.top().GetReal();
|
||||
- stack.pop();
|
||||
+ if( stack.size() == 2 )
|
||||
+ {
|
||||
+ dCurPosX = stack.top().GetReal();
|
||||
+ stack.pop();
|
||||
+ dCurPosY = stack.top().GetReal();
|
||||
+ stack.pop();
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ fprintf( stderr, "WARNING: Token '%s' expects two arguments, but %" PDF_FORMAT_INT64 " given; ignoring\n",
|
||||
+ pszToken, static_cast<pdf_int64>( stack.size() ) );
|
||||
+
|
||||
+ while( !stack.empty() )
|
||||
+ stack.pop();
|
||||
+ }
|
||||
}
|
||||
else if( strcmp( pszToken, "BT" ) == 0 )
|
||||
{
|
||||
@@ -93,6 +104,13 @@
|
||||
{
|
||||
if( strcmp( pszToken, "Tf" ) == 0 )
|
||||
{
|
||||
+ if( stack.size() < 2 )
|
||||
+ {
|
||||
+ fprintf( stderr, "WARNING: Expects two arguments for 'Tf', ignoring\n" );
|
||||
+ pCurFont = NULL;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
stack.pop();
|
||||
PdfName fontName = stack.top().GetName();
|
||||
PdfObject* pFont = pPage->GetFromResources( PdfName("Font"), fontName );
|
||||
@@ -102,21 +120,37 @@
|
||||
}
|
||||
|
||||
pCurFont = pDocument->GetFont( pFont );
|
||||
- if( !pCurFont )
|
||||
+ if( !pCurFont )
|
||||
{
|
||||
- fprintf( stderr, "WARNING: Unable to create font for object %i %i R\n",
|
||||
- pFont->Reference().ObjectNumber(),
|
||||
- pFont->Reference().GenerationNumber() );
|
||||
+ fprintf( stderr, "WARNING: Unable to create font for object %" PDF_FORMAT_INT64 " %" PDF_FORMAT_INT64 " R\n",
|
||||
+ static_cast<pdf_int64>( pFont->Reference().ObjectNumber() ),
|
||||
+ static_cast<pdf_int64>( pFont->Reference().GenerationNumber() ) );
|
||||
}
|
||||
}
|
||||
else if( strcmp( pszToken, "Tj" ) == 0 ||
|
||||
strcmp( pszToken, "'" ) == 0 )
|
||||
{
|
||||
+ if( stack.size() < 1 )
|
||||
+ {
|
||||
+ fprintf( stderr, "WARNING: Expects one argument for '%s', ignoring\n", pszToken );
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
AddTextElement( dCurPosX, dCurPosY, pCurFont, stack.top().GetString() );
|
||||
stack.pop();
|
||||
}
|
||||
else if( strcmp( pszToken, "\"" ) == 0 )
|
||||
{
|
||||
+ if( stack.size() < 3 )
|
||||
+ {
|
||||
+ fprintf( stderr, "WARNING: Expects three arguments for '%s', ignoring\n", pszToken );
|
||||
+
|
||||
+ while( !stack.empty() )
|
||||
+ stack.pop();
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
AddTextElement( dCurPosX, dCurPosY, pCurFont, stack.top().GetString() );
|
||||
stack.pop();
|
||||
stack.pop(); // remove char spacing from stack
|
||||
@@ -124,6 +158,12 @@
|
||||
}
|
||||
else if( strcmp( pszToken, "TJ" ) == 0 )
|
||||
{
|
||||
+ if( stack.size() < 3 )
|
||||
+ {
|
||||
+ fprintf( stderr, "WARNING: Expects one argument for '%s', ignoring\n", pszToken );
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
PdfArray array = stack.top().GetArray();
|
||||
stack.pop();
|
||||
|
@ -1,206 +0,0 @@
|
||||
Description: CVE-2017-8054
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Bug-Debian: https://bugs.debian.org/860995
|
||||
Origin: https://sourceforge.net/p/podofo/code/1872
|
||||
Origin: https://sourceforge.net/p/podofo/code/1881
|
||||
Origin: https://sourceforge.net/p/podofo/code/1882
|
||||
Origin: https://sourceforge.net/p/podofo/code/1883
|
||||
|
||||
--- a/src/base/PdfError.cpp
|
||||
+++ b/src/base/PdfError.cpp
|
||||
@@ -60,6 +60,12 @@
|
||||
{
|
||||
}
|
||||
|
||||
+PdfErrorInfo::PdfErrorInfo( int line, const char* pszFile, std::string sInfo )
|
||||
+ : m_nLine( line ), m_sFile( pszFile ? pszFile : "" ), m_sInfo( sInfo )
|
||||
+{
|
||||
+
|
||||
+}
|
||||
+
|
||||
PdfErrorInfo::PdfErrorInfo( int line, const char* pszFile, const char* pszInfo )
|
||||
: m_nLine( line ), m_sFile( pszFile ? pszFile : "" ), m_sInfo( pszInfo ? pszInfo : "" )
|
||||
{
|
||||
@@ -96,6 +102,12 @@
|
||||
}
|
||||
|
||||
PdfError::PdfError( const EPdfError & eCode, const char* pszFile, int line,
|
||||
+ std::string sInformation )
|
||||
+{
|
||||
+ this->SetError( eCode, pszFile, line, sInformation );
|
||||
+}
|
||||
+
|
||||
+PdfError::PdfError( const EPdfError & eCode, const char* pszFile, int line,
|
||||
const char* pszInformation )
|
||||
{
|
||||
this->SetError( eCode, pszFile, line, pszInformation );
|
||||
--- a/src/base/PdfError.h
|
||||
+++ b/src/base/PdfError.h
|
||||
@@ -158,8 +158,8 @@
|
||||
/** \def PODOFO_RAISE_ERROR_INFO( x, y )
|
||||
*
|
||||
* Set the value of the variable eCode (which has to exist in the current function) to x
|
||||
- * and return the eCode. Additionally additional information on the error y is set. y has
|
||||
- * to be an c-string.
|
||||
+ * and return the eCode. Additionally additional information on the error y is set.
|
||||
+ * y can be a C string, but can also be a C++ std::string.
|
||||
*/
|
||||
#define PODOFO_RAISE_ERROR_INFO( x, y ) throw ::PoDoFo::PdfError( x, __FILE__, __LINE__, y );
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
public:
|
||||
PdfErrorInfo();
|
||||
PdfErrorInfo( int line, const char* pszFile, const char* pszInfo );
|
||||
+ PdfErrorInfo( int line, const char* pszFile, std::string pszInfo );
|
||||
PdfErrorInfo( int line, const char* pszFile, const wchar_t* pszInfo );
|
||||
PdfErrorInfo( const PdfErrorInfo & rhs );
|
||||
|
||||
@@ -185,6 +186,7 @@
|
||||
inline const std::wstring & GetInformationW() const { return m_swInfo; }
|
||||
|
||||
inline void SetInformation( const char* pszInfo ) { m_sInfo = pszInfo ? pszInfo : ""; }
|
||||
+ inline void SetInformation( std::string pszInfo ) { m_sInfo = pszInfo; }
|
||||
inline void SetInformation( const wchar_t* pszInfo ) { m_swInfo = pszInfo ? pszInfo : L""; }
|
||||
|
||||
private:
|
||||
@@ -242,12 +244,22 @@
|
||||
* Use the compiler macro __FILE__ to initialize the field.
|
||||
* \param line the line in which the error has occured.
|
||||
* Use the compiler macro __LINE__ to initialize the field.
|
||||
- * \param pszInformation additional information on this error which mayy
|
||||
- * be formatted like printf
|
||||
+ * \param pszInformation additional information on this error
|
||||
*/
|
||||
PdfError( const EPdfError & eCode, const char* pszFile = NULL, int line = 0,
|
||||
const char* pszInformation = NULL );
|
||||
|
||||
+ /** Create a PdfError object with a given error code.
|
||||
+ * \param eCode the error code of this object
|
||||
+ * \param pszFile the file in which the error has occured.
|
||||
+ * Use the compiler macro __FILE__ to initialize the field.
|
||||
+ * \param line the line in which the error has occured.
|
||||
+ * Use the compiler macro __LINE__ to initialize the field.
|
||||
+ * \param sInformation additional information on this error
|
||||
+ */
|
||||
+ explicit PdfError( const EPdfError & eCode, const char* pszFile, int line,
|
||||
+ std::string sInformation );
|
||||
+
|
||||
/** Copy constructor
|
||||
* \param rhs copy the contents of rhs into this object
|
||||
*/
|
||||
@@ -309,6 +321,21 @@
|
||||
* \param line the line of source causing the error
|
||||
* or 0. Typically you will use the gcc
|
||||
* macro __LINE__ here.
|
||||
+ * \param sInformation additional information on the error.
|
||||
+ * e.g. how to fix the error. This string is intended to
|
||||
+ * be shown to the user.
|
||||
+ */
|
||||
+ inline void SetError( const EPdfError & eCode, const char* pszFile, int line,
|
||||
+ std::string sInformation );
|
||||
+
|
||||
+ /** Set the error code of this object.
|
||||
+ * \param eCode the error code of this object
|
||||
+ * \param pszFile the filename of the source file causing
|
||||
+ * the error or NULL. Typically you will use
|
||||
+ * the gcc macro __FILE__ here.
|
||||
+ * \param line the line of source causing the error
|
||||
+ * or 0. Typically you will use the gcc
|
||||
+ * macro __LINE__ here.
|
||||
* \param pszInformation additional information on the error.
|
||||
* e.g. how to fix the error. This string is intended to
|
||||
* be shown to the user.
|
||||
@@ -344,6 +371,21 @@
|
||||
*/
|
||||
inline void AddToCallstack( const char* pszFile = NULL, int line = 0, const char* pszInformation = NULL );
|
||||
|
||||
+ /** Add callstack information to an error object. Always call this function
|
||||
+ * if you get an error object but do not handle the error but throw it again.
|
||||
+ *
|
||||
+ * \param pszFile the filename of the source file causing
|
||||
+ * the error or NULL. Typically you will use
|
||||
+ * the gcc macro __FILE__ here.
|
||||
+ * \param line the line of source causing the error
|
||||
+ * or 0. Typically you will use the gcc
|
||||
+ * macro __LINE__ here.
|
||||
+ * \param sInformation additional information on the error.
|
||||
+ * e.g. how to fix the error. This string is intended to
|
||||
+ * be shown to the user.
|
||||
+ */
|
||||
+ inline void AddToCallstack( const char* pszFile, int line, std::string sInformation );
|
||||
+
|
||||
/** \returns true if an error code was set
|
||||
* and false if the error code is ePdfError_ErrOk
|
||||
*/
|
||||
@@ -478,6 +520,22 @@
|
||||
// -----------------------------------------------------
|
||||
//
|
||||
// -----------------------------------------------------
|
||||
+void PdfError::SetError( const EPdfError & eCode, const char* pszFile, int line, std::string sInformation )
|
||||
+{
|
||||
+ m_error = eCode;
|
||||
+ this->AddToCallstack( pszFile, line, sInformation );
|
||||
+}
|
||||
+
|
||||
+// -----------------------------------------------------
|
||||
+//
|
||||
+// -----------------------------------------------------
|
||||
+void PdfError::AddToCallstack( const char* pszFile, int line, std::string sInformation )
|
||||
+{
|
||||
+ m_callStack.push_front( PdfErrorInfo( line, pszFile, sInformation ) );
|
||||
+}
|
||||
+// -----------------------------------------------------
|
||||
+//
|
||||
+// -----------------------------------------------------
|
||||
void PdfError::SetErrorInformation( const char* pszInformation )
|
||||
{
|
||||
if( m_callStack.size() )
|
||||
--- a/src/doc/PdfPagesTree.cpp
|
||||
+++ b/src/doc/PdfPagesTree.cpp
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "PdfPagesTree.h"
|
||||
|
||||
#include "base/PdfDefinesPrivate.h"
|
||||
+#include <algorithm>
|
||||
|
||||
#include "base/PdfArray.h"
|
||||
#include "base/PdfDictionary.h"
|
||||
@@ -478,7 +479,18 @@
|
||||
if( rVar.IsArray() )
|
||||
{
|
||||
// Fixes some broken PDFs who have trees with 1 element kids arrays
|
||||
- return GetPageNodeFromArray( 0, rVar.GetArray(), rLstParents );
|
||||
+ // Recursive call removed to prevent stack overflow (CVE-2017-8054)
|
||||
+ // replaced by the following inside this conditional incl. continue
|
||||
+ const PdfArray & rVarArray = rVar.GetArray();
|
||||
+ if (rVarArray.GetSize() == 0)
|
||||
+ {
|
||||
+ PdfError::LogMessage( eLogSeverity_Critical, "Trying to access"
|
||||
+ " first page index of empty array" );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ PdfVariant rVarFirstEntry = rVarArray[0]; // avoids use-after-free
|
||||
+ rVar = rVarFirstEntry; // in this line (rVar-ref'd array is freed)
|
||||
+ continue;
|
||||
}
|
||||
else if( !rVar.IsReference() )
|
||||
{
|
||||
@@ -502,6 +514,18 @@
|
||||
if( !pgObject->GetDictionary().HasKey( "Kids" ) )
|
||||
return NULL;
|
||||
|
||||
+ if ( std::find( rLstParents.begin(), rLstParents.end(), pgObject )
|
||||
+ != rLstParents.end() ) // cycle in parent list detected, fend
|
||||
+ { // off security vulnerability CVE-2017-8054 (infinite recursion)
|
||||
+ std::ostringstream oss;
|
||||
+ oss << "Cycle in page tree: child in /Kids array of object "
|
||||
+ << ( *(rLstParents.rbegin()) )->Reference().ToString()
|
||||
+ << " back-references to object " << pgObject->Reference()
|
||||
+ .ToString() << " one of whose descendants the former is.";
|
||||
+
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_PageNotFound, oss.str() );
|
||||
+ }
|
||||
+
|
||||
rLstParents.push_back( pgObject );
|
||||
rVar = *(pgObject->GetDictionary().GetKey( "Kids" ));
|
||||
} else {
|
@ -1,22 +0,0 @@
|
||||
Description: CVE-2017-8378
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Bug-Debian: https://bugs.debian.org/861597
|
||||
Origin: https://sourceforge.net/p/podofo/code/1833
|
||||
|
||||
--- a/src/base/PdfParser.cpp
|
||||
+++ b/src/base/PdfParser.cpp
|
||||
@@ -981,6 +981,14 @@
|
||||
if( pEncrypt->IsReference() )
|
||||
{
|
||||
i = pEncrypt->GetReference().ObjectNumber();
|
||||
+ if( i <= 0 || static_cast<size_t>( i ) >= m_offsets.size () )
|
||||
+ {
|
||||
+ std::ostringstream oss;
|
||||
+ oss << "Encryption dictionary references a nonexistent object " << pEncrypt->GetReference().ObjectNumber() << " "
|
||||
+ << pEncrypt->GetReference().GenerationNumber();
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidEncryptionDict, oss.str().c_str() );
|
||||
+ }
|
||||
+
|
||||
pObject = new PdfParserObject( m_vecObjects, m_device, m_buffer, m_offsets[i].lOffset );
|
||||
if( !pObject )
|
||||
PODOFO_RAISE_ERROR( ePdfError_OutOfMemory );
|
@ -1,20 +0,0 @@
|
||||
Description: CVE-2017-8787
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Origin: https://sourceforge.net/p/podofo/code/185
|
||||
Bug-Debian: https://bugs.debian.org/861738
|
||||
Last-Update: 2017-11-12
|
||||
|
||||
--- a/src/base/PdfXRefStreamParserObject.cpp
|
||||
+++ b/src/base/PdfXRefStreamParserObject.cpp
|
||||
@@ -124,6 +124,11 @@
|
||||
pdf_long lBufferLen;
|
||||
const size_t entryLen = static_cast<size_t>(nW[0] + nW[1] + nW[2]);
|
||||
|
||||
+ if( nW[0] + nW[1] + nW[2] < 0 )
|
||||
+ {
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_NoXRef, "Invalid entry length in XRef stream" );
|
||||
+ }
|
||||
+
|
||||
this->GetStream()->GetFilteredCopy( &pBuffer, &lBufferLen );
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
Description: CVE-2018-5295
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Bug-Debian: https://bugs.debian.org/889511
|
||||
Origin: https://sourceforge.net/p/podofo/code/1889
|
||||
|
||||
--- a/src/base/PdfXRefStreamParserObject.cpp
|
||||
+++ b/src/base/PdfXRefStreamParserObject.cpp
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "PdfStream.h"
|
||||
#include "PdfVariant.h"
|
||||
|
||||
-#include <stdio.h>
|
||||
+#include <limits>
|
||||
|
||||
namespace PoDoFo {
|
||||
|
||||
@@ -122,13 +122,27 @@
|
||||
{
|
||||
char* pBuffer;
|
||||
pdf_long lBufferLen;
|
||||
- const size_t entryLen = static_cast<size_t>(nW[0] + nW[1] + nW[2]);
|
||||
|
||||
- if( nW[0] + nW[1] + nW[2] < 0 )
|
||||
+ for(pdf_int64 nLengthSum = 0, i = 0; i < W_ARRAY_SIZE; i++ )
|
||||
{
|
||||
- PODOFO_RAISE_ERROR_INFO( ePdfError_NoXRef, "Invalid entry length in XRef stream" );
|
||||
+ if ( nW[i] < 0 )
|
||||
+ {
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_NoXRef,
|
||||
+ "Negative field length in XRef stream" );
|
||||
+ }
|
||||
+ if ( std::numeric_limits<pdf_int64>::max() - nLengthSum < nW[i] )
|
||||
+ {
|
||||
+ PODOFO_RAISE_ERROR_INFO( ePdfError_NoXRef,
|
||||
+ "Invalid entry length in XRef stream" );
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ nLengthSum += nW[i];
|
||||
+ }
|
||||
}
|
||||
|
||||
+ const size_t entryLen = static_cast<size_t>(nW[0] + nW[1] + nW[2]);
|
||||
+
|
||||
this->GetStream()->GetFilteredCopy( &pBuffer, &lBufferLen );
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
Description: CVE-2018-5308
|
||||
Acked-By: Mattia Rizzolo <mattia@debian.org>
|
||||
Origin: https://sourceforge.net/p/podofo/code/1870
|
||||
Origin: https://sourceforge.net/p/podofo/code/1876
|
||||
|
||||
--- a/src/base/PdfOutputStream.cpp
|
||||
+++ b/src/base/PdfOutputStream.cpp
|
||||
@@ -85,6 +85,11 @@
|
||||
PdfMemoryOutputStream::PdfMemoryOutputStream( char* pBuffer, pdf_long lLen )
|
||||
: m_lLen( 0 ), m_bOwnBuffer( false )
|
||||
{
|
||||
+ if( !pBuffer )
|
||||
+ {
|
||||
+ PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
|
||||
+ }
|
||||
+
|
||||
m_lSize = lLen;
|
||||
m_pBuffer = pBuffer;
|
||||
}
|
||||
@@ -98,7 +103,7 @@
|
||||
|
||||
pdf_long PdfMemoryOutputStream::Write( const char* pBuffer, pdf_long lLen )
|
||||
{
|
||||
- if( !m_pBuffer )
|
||||
+ if( !pBuffer )
|
||||
{
|
||||
PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
diff -rupN podofo-0.9.4/test/unit/EncryptTest.h podofo-0.9.4-new/test/unit/EncryptTest.h
|
||||
--- podofo-0.9.4/test/unit/EncryptTest.h 2012-12-12 23:55:46.000000000 +0100
|
||||
+++ podofo-0.9.4-new/test/unit/EncryptTest.h 2016-09-18 10:41:30.476635230 +0200
|
||||
@@ -83,7 +83,7 @@ class EncryptTest : public CppUnit::Test
|
||||
|
||||
private:
|
||||
char* m_pEncBuffer;
|
||||
- long m_lLen;
|
||||
+ PoDoFo::pdf_long m_lLen;
|
||||
int m_protection;
|
||||
|
||||
};
|
@ -1,12 +0,0 @@
|
||||
diff -rupN podofo-0.9.5/CMakeLists.txt podofo-0.9.5-new/CMakeLists.txt
|
||||
--- podofo-0.9.5/CMakeLists.txt 2017-02-01 22:23:03.000000000 +0100
|
||||
+++ podofo-0.9.5-new/CMakeLists.txt 2017-02-10 14:40:25.472066545 +0100
|
||||
@@ -296,8 +296,6 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
SET(PODOFO_USE_VISIBILITY ${PODOFO_HAVE_GCC4})
|
||||
ENDIF(NOT DEFINED PODOFO_USE_VISIBILITY)
|
||||
|
||||
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98")
|
||||
-
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Woverloaded-virtual -Wswitch-enum -Wcast-qual -Wwrite-strings -Wredundant-decls -Wreorder")
|
||||
|
||||
#
|
Loading…
Reference in new issue