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);
}
[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]
public void ReadsNumericObjectWithComment()
{

View File

@ -162,6 +162,10 @@
}
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)
{

View File

@ -148,7 +148,8 @@
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);

View File

@ -43,9 +43,13 @@
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);
if (temp is null)
{
return null;
}
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}.");
}
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)
{
@ -84,32 +88,7 @@
if (token is IndirectReferenceToken reference)
{
var temp = scanner.Get(reference.Data);
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;
}
}
return Get<T>(reference.Data, scanner);
}
throw new PdfDocumentFormatException($"Could not find the object {token} with type {typeof(T).Name}.");

View File

@ -32,7 +32,7 @@
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))
{

View File

@ -138,7 +138,7 @@
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;
}

View File

@ -45,7 +45,7 @@
/// <returns>The tokenized PDF object from the file.</returns>
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>
/// Tokenize the object with a given object number.
/// May return null when the reference is undefined
/// </summary>
/// <param name="reference">The object number for the object to tokenize.</param>
/// <returns>The tokenized object.</returns>

View File

@ -664,7 +664,7 @@
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.