45
45
46
46
using namespace PDFHummus ;
47
47
48
+ #define MAX_OBJECT_DEPTH 100 // While PDF does not explicitly define arrays and dicts depth...we do, due to call stack depth limit...and to avoid potential malarky.
49
+
48
50
49
51
PDFObjectParser::PDFObjectParser (void )
50
52
{
51
53
mParserExtender = NULL ;
52
54
mDecryptionHelper = NULL ;
53
55
mOwnsStream = false ;
54
56
mStream = NULL ;
57
+ mDepth = 0 ;
55
58
}
56
59
57
60
PDFObjectParser::~PDFObjectParser (void )
@@ -79,6 +82,7 @@ void PDFObjectParser::ResetReadState()
79
82
{
80
83
mTokenBuffer .clear ();
81
84
mTokenizer .ResetReadState ();
85
+ mDepth = 0 ;
82
86
}
83
87
84
88
void PDFObjectParser::ResetReadState (const PDFParserTokenizer& inExternalTokenizer)
@@ -584,14 +588,40 @@ bool PDFObjectParser::IsArray(const std::string& inToken)
584
588
return scLeftSquare == inToken;
585
589
}
586
590
591
+ EStatusCode PDFObjectParser::IncreaseAndCheckDepth () {
592
+ ++mDepth ;
593
+ if (mDepth > MAX_OBJECT_DEPTH) {
594
+ TRACE_LOG1 (" PDFObjectParser::IncreaseAndCeckDepth, reached maximum allowed depth of %d" , MAX_OBJECT_DEPTH);
595
+ return eFailure;
596
+ }
597
+
598
+ return eSuccess;
599
+ }
600
+
601
+ EStatusCode PDFObjectParser::DecreaseAndCheckDepth () {
602
+ --mDepth ;
603
+ if (mDepth < 0 ) {
604
+ TRACE_LOG (" PDFObjectParser::DecreaseAndCheckDepth, anomaly. managed to get to negative depth" );
605
+ return eFailure;
606
+ }
607
+
608
+ return eSuccess;
609
+ }
610
+
611
+
587
612
static const std::string scRightSquare = " ]" ;
588
613
PDFObject* PDFObjectParser::ParseArray ()
589
614
{
590
- PDFArray* anArray = new PDFArray () ;
615
+ PDFArray* anArray;
591
616
bool arrayEndEncountered = false ;
592
617
std::string token;
593
618
EStatusCode status = PDFHummus::eSuccess;
594
619
620
+ if (IncreaseAndCheckDepth () != eSuccess)
621
+ return NULL ;
622
+
623
+ anArray = new PDFArray ();
624
+
595
625
// easy one. just loop till you get to a closing bracket token and recurse
596
626
while (GetNextToken (token) && PDFHummus::eSuccess == status)
597
627
{
@@ -612,6 +642,9 @@ PDFObject* PDFObjectParser::ParseArray()
612
642
}
613
643
}
614
644
645
+ if (DecreaseAndCheckDepth () != eSuccess)
646
+ status = eFailure;
647
+
615
648
if (arrayEndEncountered && PDFHummus::eSuccess == status)
616
649
{
617
650
return anArray;
@@ -643,11 +676,16 @@ bool PDFObjectParser::IsDictionary(const std::string& inToken)
643
676
static const std::string scDoubleRightAngle = " >>" ;
644
677
PDFObject* PDFObjectParser::ParseDictionary ()
645
678
{
646
- PDFDictionary* aDictionary = new PDFDictionary () ;
679
+ PDFDictionary* aDictionary;
647
680
bool dictionaryEndEncountered = false ;
648
681
std::string token;
649
682
EStatusCode status = PDFHummus::eSuccess;
650
683
684
+ if (IncreaseAndCheckDepth () != eSuccess)
685
+ return NULL ;
686
+
687
+ aDictionary = new PDFDictionary ();
688
+
651
689
while (GetNextToken (token) && PDFHummus::eSuccess == status)
652
690
{
653
691
dictionaryEndEncountered = (scDoubleRightAngle == token);
@@ -681,6 +719,9 @@ PDFObject* PDFObjectParser::ParseDictionary()
681
719
aDictionary->Insert (aKey.GetPtr (),aValue.GetPtr ());
682
720
}
683
721
722
+ if (DecreaseAndCheckDepth () != eSuccess)
723
+ status = eFailure;
724
+
684
725
if (dictionaryEndEncountered && PDFHummus::eSuccess == status)
685
726
{
686
727
return aDictionary;
0 commit comments