Merge pull request #197 from Poltuu/fix_undefined_references

FIX : undefined references is a valid use case.
This commit is contained in:
Eliot Jones 2020-08-19 17:48:09 +01:00 committed by GitHub
commit 6f26b274c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 48 additions and 33 deletions

View File

@ -50,6 +50,36 @@ endobj";
Assert.Equal(new IndirectReference(12, 7), reference.Data); Assert.Equal(new IndirectReference(12, 7), reference.Data);
} }
[Fact]
public void ReadsObjectWithUndefinedIndirectReference()
{
const string s = @"
5 0 obj
<<
/XObject <<
/Pic1 7 0 R
>>
/ProcSet [/PDF /Text /ImageC ]
/Font <<
/F0 8 0 R
/F1 9 0 R
/F2 10 0 R
/F3 0 0 R
>>
>>
endobj";
var scanner = GetScanner(s);
ReadToEnd(scanner);
var token = scanner.Get(new IndirectReference(5, 0));
Assert.NotNull(token);
token = scanner.Get(new IndirectReference(0, 0));
Assert.Null(token);
}
[Fact] [Fact]
public void ReadsNumericObjectWithComment() public void ReadsNumericObjectWithComment()
{ {

View File

@ -162,6 +162,10 @@
} }
var kidObject = tokenScanner.Get(kidReferenceToken.Data); var kidObject = tokenScanner.Get(kidReferenceToken.Data);
if (kidObject is null)
{
throw new InvalidOperationException($"Could not find the object with reference: {kidReferenceToken.Data}.");
}
if (kidObject.Data is DictionaryToken kidDictionaryToken) if (kidObject.Data is DictionaryToken kidDictionaryToken)
{ {

View File

@ -148,7 +148,8 @@
if (fontObject == null) if (fontObject == null)
{ {
throw new InvalidOperationException($"Could not retrieve the font with name: {pair.Key} which should have been object {objectKey}"); //This is a valid use case
continue;
} }
loadedFonts[reference] = fontFactory.Get(fontObject); loadedFonts[reference] = fontFactory.Get(fontObject);

View File

@ -43,9 +43,13 @@
return false; return false;
} }
public static T Get<T>(IndirectReference reference, IPdfTokenScanner scanner) where T : IToken public static T Get<T>(IndirectReference reference, IPdfTokenScanner scanner) where T : class, IToken
{ {
var temp = scanner.Get(reference); var temp = scanner.Get(reference);
if (temp is null)
{
return null;
}
if (temp.Data is T locatedResult) if (temp.Data is T locatedResult)
{ {
@ -75,7 +79,7 @@
throw new PdfDocumentFormatException($"Could not find the object number {reference} with type {typeof(T).Name}."); throw new PdfDocumentFormatException($"Could not find the object number {reference} with type {typeof(T).Name}.");
} }
public static T Get<T>(IToken token, IPdfTokenScanner scanner) where T : IToken public static T Get<T>(IToken token, IPdfTokenScanner scanner) where T : class, IToken
{ {
if (token is T result) if (token is T result)
{ {
@ -84,32 +88,7 @@
if (token is IndirectReferenceToken reference) if (token is IndirectReferenceToken reference)
{ {
var temp = scanner.Get(reference.Data); return Get<T>(reference.Data, scanner);
if (temp.Data is T locatedResult)
{
return locatedResult;
}
if (temp.Data is IndirectReferenceToken nestedReference)
{
return Get<T>(nestedReference, scanner);
}
if (temp.Data is ArrayToken array && array.Data.Count == 1)
{
var arrayElement = array.Data[0];
if (arrayElement is IndirectReferenceToken arrayReference)
{
return Get<T>(arrayReference, scanner);
}
if (arrayElement is T arrayToken)
{
return arrayToken;
}
}
} }
throw new PdfDocumentFormatException($"Could not find the object {token} with type {typeof(T).Name}."); throw new PdfDocumentFormatException($"Could not find the object {token} with type {typeof(T).Name}.");

View File

@ -32,7 +32,7 @@
return true; return true;
} }
internal static T Get<T>(this DictionaryToken dictionary, NameToken name, IPdfTokenScanner scanner) where T : IToken internal static T Get<T>(this DictionaryToken dictionary, NameToken name, IPdfTokenScanner scanner) where T : class, IToken
{ {
if (!dictionary.TryGet(name, out var token) || !(token is T typedToken)) if (!dictionary.TryGet(name, out var token) || !(token is T typedToken))
{ {

View File

@ -138,7 +138,7 @@
try try
{ {
if (!(pdfScanner.Get(descriptor.FontFile.ObjectKey.Data).Data is StreamToken stream)) if (!(pdfScanner.Get(descriptor.FontFile.ObjectKey.Data)?.Data is StreamToken stream))
{ {
return null; return null;
} }

View File

@ -45,7 +45,7 @@
/// <returns>The tokenized PDF object from the file.</returns> /// <returns>The tokenized PDF object from the file.</returns>
public ObjectToken GetObject(IndirectReference reference) public ObjectToken GetObject(IndirectReference reference)
{ {
return TokenScanner.Get(reference); return TokenScanner.Get(reference) ?? throw new InvalidOperationException($"Could not find the object with reference: {reference}.");
} }
} }
} }

View File

@ -11,6 +11,7 @@
{ {
/// <summary> /// <summary>
/// Tokenize the object with a given object number. /// Tokenize the object with a given object number.
/// May return null when the reference is undefined
/// </summary> /// </summary>
/// <param name="reference">The object number for the object to tokenize.</param> /// <param name="reference">The object number for the object to tokenize.</param>
/// <returns>The tokenized object.</returns> /// <returns>The tokenized object.</returns>

View File

@ -664,7 +664,7 @@
if (!objectLocationProvider.TryGetOffset(reference, out var offset)) if (!objectLocationProvider.TryGetOffset(reference, out var offset))
{ {
throw new InvalidOperationException($"Could not find the object with reference: {reference}."); return null;
} }
// Negative offsets refer to a stream with that number. // Negative offsets refer to a stream with that number.