Track IndirectReference instead of only ObjectNumber when checking for cycles during indirect reference resolutionv and add test

This commit is contained in:
BobLd 2025-07-20 18:27:51 +01:00
parent 2b11961c8c
commit 813d3baa18
3 changed files with 25 additions and 4 deletions

View File

@ -7,6 +7,27 @@
public class GithubIssuesTests public class GithubIssuesTests
{ {
[Fact]
public void Issue1096()
{
// Ensure no StackOverflowException
// (already fixed by https://github.com/UglyToad/PdfPig/pull/1097)
var path = IntegrationHelpers.GetSpecificTestDocumentPath("issue_1096.pdf");
using (var document = PdfDocument.Open(path, new ParsingOptions() { UseLenientParsing = true }))
{
for (int p = 1; p <= document.NumberOfPages; p++)
{
var page = document.GetPage(p);
foreach (var image in page.GetImages())
{
Assert.NotNull(image);
}
}
}
}
[Fact] [Fact]
public void Issue1067() public void Issue1067()
{ {

View File

@ -122,12 +122,12 @@
/// Returns an equivalent token where any indirect references of child objects are /// Returns an equivalent token where any indirect references of child objects are
/// recursively traversed and resolved. /// recursively traversed and resolved.
/// </summary> /// </summary>
internal static T? Resolve<T>(this T? token, IPdfTokenScanner scanner, List<long>? visited = null) where T : IToken internal static T? Resolve<T>(this T? token, IPdfTokenScanner scanner, List<IndirectReference>? visited = null) where T : IToken
{ {
return (T?)ResolveInternal(token, scanner, visited ?? []); return (T?)ResolveInternal(token, scanner, visited ?? []);
} }
private static IToken? ResolveInternal(this IToken? token, IPdfTokenScanner scanner, List<long> visited) private static IToken? ResolveInternal(this IToken? token, IPdfTokenScanner scanner, List<IndirectReference> visited)
{ {
if (token is StreamToken stream) if (token is StreamToken stream)
{ {
@ -142,12 +142,12 @@
var value = kvp.Value; var value = kvp.Value;
if (kvp.Value is IndirectReferenceToken reference) if (kvp.Value is IndirectReferenceToken reference)
{ {
if (visited.Contains(reference.Data.ObjectNumber)) if (visited.Contains(reference.Data))
{ {
continue; continue;
} }
value = scanner.Get(reference.Data)?.Data; value = scanner.Get(reference.Data)?.Data;
visited.Add(reference.Data.ObjectNumber); visited.Add(reference.Data);
} }
resolvedItems[NameToken.Create(kvp.Key)] = ResolveInternal(value, scanner, visited); resolvedItems[NameToken.Create(kvp.Key)] = ResolveInternal(value, scanner, visited);
} }