mirror of
https://github.com/UglyToad/PdfPig.git
synced 2026-02-19 08:46:16 +08:00
Improve HasFormXObjectCircularReference and fix #1250
This commit is contained in:
Binary file not shown.
@@ -11,6 +11,31 @@
|
||||
|
||||
public class GithubIssuesTests
|
||||
{
|
||||
[Fact]
|
||||
public void Issues1250()
|
||||
{
|
||||
// Issue comes from HasFormXObjectCircularReference
|
||||
var path = IntegrationHelpers.GetDocumentPath("SPE8EF26T0545.pdf");
|
||||
using (var document = PdfDocument.Open(path, new ParsingOptions() { UseLenientParsing = true }))
|
||||
{
|
||||
var page = document.GetPage(1);
|
||||
Assert.NotNull(page);
|
||||
Assert.NotEmpty(page.Letters);
|
||||
|
||||
page = document.GetPage(7);
|
||||
Assert.NotNull(page);
|
||||
Assert.NotEmpty(page.Letters);
|
||||
}
|
||||
|
||||
// Ensure still no StackOverflowException
|
||||
using (var document = PdfDocument.Open(IntegrationHelpers.GetDocumentPath("issue_671")))
|
||||
{
|
||||
var page = document.GetPage(1);
|
||||
Assert.NotNull(page);
|
||||
Assert.NotEmpty(page.Letters);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Issues1248()
|
||||
{
|
||||
@@ -29,7 +54,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Issues1238()
|
||||
{
|
||||
|
||||
@@ -587,7 +587,8 @@
|
||||
if (hasCircularReference)
|
||||
{
|
||||
if (ParsingOptions.UseLenientParsing)
|
||||
{
|
||||
{
|
||||
// TODO - We might be removing too much, good for the moment. See Issues1250() for examples
|
||||
operations = operations.Where(o => o is not InvokeNamedXObject xo || xo.Name != xObjectName)
|
||||
.ToArray();
|
||||
ParsingOptions.Logger.Warn(
|
||||
@@ -618,14 +619,56 @@
|
||||
/// <param name="xObjectName">The form's name.</param>
|
||||
/// <param name="operations">The form operations parsed from original form stream.</param>
|
||||
protected virtual bool HasFormXObjectCircularReference(StreamToken formStream,
|
||||
NameToken xObjectName,
|
||||
NameToken? xObjectName,
|
||||
IReadOnlyList<IGraphicsStateOperation> operations)
|
||||
{
|
||||
return xObjectName != null
|
||||
&& operations.OfType<InvokeNamedXObject>()?.Any(o => o.Name == xObjectName) ==
|
||||
true // operations contain another form with same name
|
||||
&& ResourceStore.TryGetXObject(xObjectName, out var result)
|
||||
&& result.Data.Span.SequenceEqual(formStream.Data.Span); // The form contained in the operations has identical data to current form
|
||||
if (xObjectName is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (operations.OfType<InvokeNamedXObject>()?.Any(o => o.Name == xObjectName) != true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TryGetXObjectToken(formStream, xObjectName, PdfScanner, out var t1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ResourceStore.TryGetXObject(xObjectName, out var resourceStream))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TryGetXObjectToken(resourceStream, xObjectName, PdfScanner, out var t2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t1 is null || t2 is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return t1.Equals(t2);
|
||||
|
||||
static bool TryGetXObjectToken(StreamToken streamToken, NameToken xObjectName, IPdfTokenScanner scanner, out IToken? token)
|
||||
{
|
||||
token = null;
|
||||
if (!streamToken.StreamDictionary.TryGet<DictionaryToken>(NameToken.Resources, scanner, out var formResources))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!formResources.TryGet<DictionaryToken>(NameToken.Xobject, out var xObjectBase) || !xObjectBase.TryGet(xObjectName, out token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return token is not null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
||||
Reference in New Issue
Block a user