Skip to content

Commit 67d8f56

Browse files
committed
Do not throw exception when lenient parsing in GetExtendedGraphicsStateDictionary() and improve StackDictionary.TryGetValue() to not throw on empty
1 parent f26e7d9 commit 67d8f56

File tree

5 files changed

+43
-4
lines changed

5 files changed

+43
-4
lines changed

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

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

88
public class GithubIssuesTests
99
{
10+
[Fact]
11+
public void Issue953()
12+
{
13+
// NB: We actually do not fix issue 953 here, but another bug found with the same document.
14+
var path = IntegrationHelpers.GetSpecificTestDocumentPath("FailedToParseContentForPage32.pdf");
15+
16+
// Lenient parsing ON + Skip missing fonts
17+
using (var document = PdfDocument.Open(path, new ParsingOptions() { UseLenientParsing = true, SkipMissingFonts = true}))
18+
{
19+
var page = document.GetPage(33);
20+
Assert.Equal(33, page.Number);
21+
Assert.Equal(792, page.Height);
22+
Assert.Equal(612, page.Width);
23+
}
24+
25+
// Lenient parsing ON + Do not Skip missing fonts
26+
using (var document = PdfDocument.Open(path, new ParsingOptions() { UseLenientParsing = true, SkipMissingFonts = false }))
27+
{
28+
var pageException = Assert.Throws<InvalidOperationException>(() => document.GetPage(33));
29+
Assert.Equal("Could not find the font with name /TT4 in the resource store. It has not been loaded yet.", pageException.Message);
30+
}
31+
32+
var docException = Assert.Throws<PdfDocumentFormatException>(() =>
33+
PdfDocument.Open(path, new ParsingOptions() { UseLenientParsing = false, SkipMissingFonts = false }));
34+
Assert.Equal("Could not find dictionary associated with reference in pages kids array: 102 0.", docException.Message);
35+
}
36+
1037
[Fact]
1138
public void Issue987()
1239
{
Binary file not shown.

src/UglyToad.PdfPig/Content/IResourceStore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public interface IResourceStore
3535
/// <summary>
3636
/// Get the extended graphics state dictionary corresponding to the name.
3737
/// </summary>
38-
DictionaryToken GetExtendedGraphicsStateDictionary(NameToken name);
38+
DictionaryToken? GetExtendedGraphicsStateDictionary(NameToken name);
3939

4040
/// <summary>
4141
/// Get the font from the <see cref="IndirectReferenceToken"/>.

src/UglyToad.PdfPig/Content/ResourceStore.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,14 @@ public bool TryGetXObject(NameToken name, [NotNullWhen(true)] out StreamToken? s
336336
return DirectObjectFinder.TryGet(new IndirectReferenceToken(indirectReference), scanner, out stream);
337337
}
338338

339-
public DictionaryToken GetExtendedGraphicsStateDictionary(NameToken name)
339+
public DictionaryToken? GetExtendedGraphicsStateDictionary(NameToken name)
340340
{
341+
if (parsingOptions.UseLenientParsing && !extendedGraphicsStates.ContainsKey(name))
342+
{
343+
parsingOptions.Logger.Error($"The graphic state dictionary does not contain the key '{name}'.");
344+
return null;
345+
}
346+
341347
return extendedGraphicsStates[name];
342348
}
343349

src/UglyToad.PdfPig/Util/StackDictionary.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@ namespace UglyToad.PdfPig.Util
55
using System.Collections.Generic;
66
using System.Diagnostics.CodeAnalysis;
77

8-
internal class StackDictionary<K, V> where K : notnull
8+
internal sealed class StackDictionary<K, V> where K : notnull
99
{
1010
private readonly List<Dictionary<K, V>> values = new List<Dictionary<K, V>>();
1111

1212
public V this[K key]
1313
{
1414
get
1515
{
16+
if (values.Count == 0)
17+
{
18+
throw new InvalidOperationException($"Cannot get item from empty stack, call {nameof(Push)} before use.");
19+
}
20+
1621
if (TryGetValue(key, out var result))
1722
{
1823
return result;
@@ -35,7 +40,8 @@ public bool TryGetValue(K key, [NotNullWhen(true)] out V result)
3540
{
3641
if (values.Count == 0)
3742
{
38-
throw new InvalidOperationException($"Cannot get item from empty stack, call {nameof(Push)} before use.");
43+
result = default!;
44+
return false;
3945
}
4046

4147
for (var i = values.Count - 1; i >= 0; i--)

0 commit comments

Comments
 (0)