diff --git a/src/UglyToad.PdfPig.Tests/Integration/Documents/MOZILLA-9176-2.pdf b/src/UglyToad.PdfPig.Tests/Integration/Documents/MOZILLA-9176-2.pdf new file mode 100644 index 000000000..72cb0df75 Binary files /dev/null and b/src/UglyToad.PdfPig.Tests/Integration/Documents/MOZILLA-9176-2.pdf differ diff --git a/src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs b/src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs index 0942f718e..4a73f8f9d 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs @@ -29,6 +29,33 @@ public void Issue1208() } } + [Fact] + public void Issue1209() + { + var path = IntegrationHelpers.GetDocumentPath("MOZILLA-9176-2.pdf"); + + using (var document = PdfDocument.Open(path, new ParsingOptions() { UseLenientParsing = true })) + { + for (int p = 1; p <= document.NumberOfPages; p++) + { + var page = document.GetPage(p); + Assert.NotNull(page); + + foreach (var image in page.GetImages()) + { + Assert.True(image.ImageDictionary.ContainsKey(NameToken.Height)); // Was missing + Assert.True(image.ImageDictionary.ContainsKey(NameToken.Width)); + + if (image.ImageDictionary.TryGet(NameToken.DecodeParms, out var decodeParms)) + { + Assert.True(decodeParms.ContainsKey(NameToken.Columns)); // Was missing + Assert.True(decodeParms.ContainsKey(NameToken.Rows)); + } + } + } + } + } + [Fact] public void Revert_e11dc6b() { diff --git a/src/UglyToad.PdfPig/PdfExtensions.cs b/src/UglyToad.PdfPig/PdfExtensions.cs index 64bff2e01..59c340580 100644 --- a/src/UglyToad.PdfPig/PdfExtensions.cs +++ b/src/UglyToad.PdfPig/PdfExtensions.cs @@ -2,6 +2,7 @@ { using System; using System.Diagnostics.CodeAnalysis; + using System.Linq; using Core; using Filters; using Parser.Parts; @@ -156,6 +157,23 @@ private static double GetEstimatedSizeMultiplier(IFilter filter) resolvedItems[NameToken.Create(kvp.Key)] = ResolveInternal(value, scanner, visited); } + if (resolvedItems.Count != dict.Data.Count) + { + if (resolvedItems.Count > dict.Data.Count) + { + throw new InvalidOperationException("Resolved more items than were present in the original dictionary. This should not be possible."); + } + + // We missed some due to cycles, try and resolve them now. + foreach (var missing in dict.Data.Keys.Except(resolvedItems.Keys.Select(k => k.Data), StringComparer.OrdinalIgnoreCase)) + { + if (dict.Data[missing] is IndirectReferenceToken reference) + { + resolvedItems[NameToken.Create(missing)] = ResolveInternal(reference, scanner, visited); + } + } + } + return new DictionaryToken(resolvedItems); }