Skip to content

Commit 8b695df

Browse files
committed
Prevent StackOverflow in ParseTrailer and fix UglyToad#1122
1 parent f1923fc commit 8b695df

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77

88
public class GithubIssuesTests
99
{
10+
[Fact]
11+
public void Issue1122()
12+
{
13+
var path = IntegrationHelpers.GetSpecificTestDocumentPath("StackOverflow_Issue_1122.pdf");
14+
15+
var ex = Assert.Throws<PdfDocumentFormatException>(() => PdfDocument.Open(path, new ParsingOptions() { UseLenientParsing = true }));
16+
Assert.StartsWith("Reached maximum search depth while getting indirect reference.", ex.Message);
17+
}
18+
1019
[Fact]
1120
public void Issue1096()
1221
{
Binary file not shown.

src/UglyToad.PdfPig/Tokenization/Scanner/PdfTokenScanner.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,8 @@ private DictionaryToken GetStreamDictionary()
625625
{
626626
if (offset < 0)
627627
{
628-
var result = GetObjectFromStream(lengthReference.Data, offset);
628+
ushort searchDepth = 0;
629+
var result = GetObjectFromStream(lengthReference.Data, offset, searchDepth);
629630

630631
if (!(result.Data is NumericToken streamLengthToken))
631632
{
@@ -714,9 +715,23 @@ public void DeregisterCustomTokenizer(ITokenizer tokenizer)
714715

715716
coreTokenScanner.DeregisterCustomTokenizer(tokenizer);
716717
}
717-
718+
718719
public ObjectToken? Get(IndirectReference reference)
719720
{
721+
ushort searchDepth = 0;
722+
return Get(reference, searchDepth);
723+
}
724+
725+
private ObjectToken? Get(IndirectReference reference, ushort searchDepth)
726+
{
727+
if (searchDepth > 1_000)
728+
{
729+
throw new PdfDocumentFormatException("Reached maximum search depth while getting indirect reference.");
730+
}
731+
732+
searchDepth++;
733+
734+
720735
if (isDisposed)
721736
{
722737
throw new ObjectDisposedException(nameof(PdfTokenScanner));
@@ -740,7 +755,7 @@ public void DeregisterCustomTokenizer(ITokenizer tokenizer)
740755
// Negative offsets refer to a stream with that number.
741756
if (offset < 0)
742757
{
743-
var result = GetObjectFromStream(reference, offset);
758+
var result = GetObjectFromStream(reference, offset, searchDepth);
744759

745760
return result;
746761
}
@@ -802,11 +817,11 @@ private ObjectToken BruteForceFileToFindReference(IndirectReference reference)
802817
}
803818
}
804819

805-
private ObjectToken GetObjectFromStream(IndirectReference reference, long offset)
820+
private ObjectToken GetObjectFromStream(IndirectReference reference, long offset, ushort searchDepth)
806821
{
807822
var streamObjectNumber = offset * -1;
808823

809-
var streamObject = Get(new IndirectReference(streamObjectNumber, 0));
824+
var streamObject = Get(new IndirectReference(streamObjectNumber, 0), searchDepth);
810825

811826
if (!(streamObject?.Data is StreamToken stream))
812827
{

0 commit comments

Comments
 (0)