mirror of
https://github.com/UglyToad/PdfPig.git
synced 2026-03-10 00:23:29 +08:00
#405 check encryption token value for null
This commit is contained in:
@@ -417,6 +417,35 @@ endobj";
|
|||||||
Assert.Equal(3, third.Number.ObjectNumber);
|
Assert.Equal(3, third.Number.ObjectNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ReadsDictionaryContainingNull()
|
||||||
|
{
|
||||||
|
const string input = @"14224 0 obj
|
||||||
|
<</Type /XRef
|
||||||
|
/Root 8 0 R
|
||||||
|
/Prev 116
|
||||||
|
/Length 84
|
||||||
|
/Size 35
|
||||||
|
/W [1 3 2]
|
||||||
|
/Index [0 1 6 1 8 2 25 10]
|
||||||
|
/ID [ (ù¸7<C2B8>ãA×<41>žòÜ4<C39C><34>Š•)]
|
||||||
|
/Info 6 0 R
|
||||||
|
/Encrypt null>>
|
||||||
|
endobj";
|
||||||
|
|
||||||
|
var scanner = GetScanner(input);
|
||||||
|
|
||||||
|
var tokens = ReadToEnd(scanner);
|
||||||
|
|
||||||
|
var dictionaryToken = tokens[0].Data as DictionaryToken;
|
||||||
|
|
||||||
|
Assert.NotNull(dictionaryToken);
|
||||||
|
|
||||||
|
var encryptValue = dictionaryToken.Data["Encrypt"];
|
||||||
|
|
||||||
|
Assert.IsType<NullToken>(encryptValue);
|
||||||
|
}
|
||||||
|
|
||||||
private static PdfTokenScanner GetScanner(string s, TestObjectLocationProvider locationProvider = null)
|
private static PdfTokenScanner GetScanner(string s, TestObjectLocationProvider locationProvider = null)
|
||||||
{
|
{
|
||||||
var input = StringBytesTestConverter.Convert(s, false);
|
var input = StringBytesTestConverter.Convert(s, false);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
private static PdfDocument Open(IInputBytes inputBytes, ParsingOptions options = null)
|
private static PdfDocument Open(IInputBytes inputBytes, ParsingOptions options = null)
|
||||||
{
|
{
|
||||||
var isLenientParsing = options?.UseLenientParsing ?? true;
|
var isLenientParsing = options?.UseLenientParsing ?? true;
|
||||||
|
|
||||||
var tokenScanner = new CoreTokenScanner(inputBytes);
|
var tokenScanner = new CoreTokenScanner(inputBytes);
|
||||||
|
|
||||||
var passwords = new List<string>();
|
var passwords = new List<string>();
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PdfDocument OpenDocument(IInputBytes inputBytes, ISeekableTokenScanner scanner, ILog log, bool isLenientParsing,
|
private static PdfDocument OpenDocument(IInputBytes inputBytes, ISeekableTokenScanner scanner, ILog log, bool isLenientParsing,
|
||||||
IReadOnlyList<string> passwords, bool clipPaths)
|
IReadOnlyList<string> passwords, bool clipPaths)
|
||||||
{
|
{
|
||||||
var filterProvider = new FilterProviderWithLookup(DefaultFilterProvider.Instance);
|
var filterProvider = new FilterProviderWithLookup(DefaultFilterProvider.Instance);
|
||||||
@@ -96,25 +96,25 @@
|
|||||||
|
|
||||||
var crossReferenceStreamParser = new CrossReferenceStreamParser(filterProvider);
|
var crossReferenceStreamParser = new CrossReferenceStreamParser(filterProvider);
|
||||||
var crossReferenceParser = new CrossReferenceParser(log, xrefValidator, crossReferenceStreamParser);
|
var crossReferenceParser = new CrossReferenceParser(log, xrefValidator, crossReferenceStreamParser);
|
||||||
|
|
||||||
var version = FileHeaderParser.Parse(scanner, isLenientParsing, log);
|
var version = FileHeaderParser.Parse(scanner, isLenientParsing, log);
|
||||||
|
|
||||||
var crossReferenceOffset = FileTrailerParser.GetFirstCrossReferenceOffset(inputBytes, scanner,
|
var crossReferenceOffset = FileTrailerParser.GetFirstCrossReferenceOffset(inputBytes, scanner,
|
||||||
isLenientParsing) + version.OffsetInFile;
|
isLenientParsing) + version.OffsetInFile;
|
||||||
|
|
||||||
// TODO: make this use the scanner.
|
// TODO: make this use the scanner.
|
||||||
var validator = new CrossReferenceOffsetValidator(xrefValidator);
|
var validator = new CrossReferenceOffsetValidator(xrefValidator);
|
||||||
|
|
||||||
crossReferenceOffset = validator.Validate(crossReferenceOffset, scanner, inputBytes, isLenientParsing);
|
crossReferenceOffset = validator.Validate(crossReferenceOffset, scanner, inputBytes, isLenientParsing);
|
||||||
|
|
||||||
crossReferenceTable = crossReferenceParser.Parse(inputBytes, isLenientParsing,
|
crossReferenceTable = crossReferenceParser.Parse(inputBytes, isLenientParsing,
|
||||||
crossReferenceOffset,
|
crossReferenceOffset,
|
||||||
version.OffsetInFile,
|
version.OffsetInFile,
|
||||||
pdfScanner,
|
pdfScanner,
|
||||||
scanner);
|
scanner);
|
||||||
|
|
||||||
var (rootReference, rootDictionary) = ParseTrailer(crossReferenceTable, isLenientParsing,
|
var (rootReference, rootDictionary) = ParseTrailer(crossReferenceTable, isLenientParsing,
|
||||||
pdfScanner,
|
pdfScanner,
|
||||||
out var encryptionDictionary);
|
out var encryptionDictionary);
|
||||||
|
|
||||||
var encryptionHandler = encryptionDictionary != null ?
|
var encryptionHandler = encryptionDictionary != null ?
|
||||||
@@ -134,22 +134,22 @@
|
|||||||
type1Handler),
|
type1Handler),
|
||||||
type1Handler,
|
type1Handler,
|
||||||
new Type3FontHandler(pdfScanner, filterProvider, encodingReader));
|
new Type3FontHandler(pdfScanner, filterProvider, encodingReader));
|
||||||
|
|
||||||
var resourceContainer = new ResourceStore(pdfScanner, fontFactory);
|
var resourceContainer = new ResourceStore(pdfScanner, fontFactory);
|
||||||
|
|
||||||
var information = DocumentInformationFactory.Create(pdfScanner, crossReferenceTable.Trailer);
|
var information = DocumentInformationFactory.Create(pdfScanner, crossReferenceTable.Trailer);
|
||||||
|
|
||||||
var catalog = CatalogFactory.Create(rootReference, rootDictionary, pdfScanner, isLenientParsing);
|
var catalog = CatalogFactory.Create(rootReference, rootDictionary, pdfScanner, isLenientParsing);
|
||||||
|
|
||||||
var pageFactory = new PageFactory(pdfScanner, resourceContainer, filterProvider,
|
var pageFactory = new PageFactory(pdfScanner, resourceContainer, filterProvider,
|
||||||
new PageContentParser(new ReflectionGraphicsStateOperationFactory()),
|
new PageContentParser(new ReflectionGraphicsStateOperationFactory()),
|
||||||
log);
|
log);
|
||||||
|
|
||||||
var caching = new ParsingCachingProviders(resourceContainer);
|
var caching = new ParsingCachingProviders(resourceContainer);
|
||||||
|
|
||||||
var acroFormFactory = new AcroFormFactory(pdfScanner, filterProvider, crossReferenceTable);
|
var acroFormFactory = new AcroFormFactory(pdfScanner, filterProvider, crossReferenceTable);
|
||||||
var bookmarksProvider = new BookmarksProvider(log, pdfScanner);
|
var bookmarksProvider = new BookmarksProvider(log, pdfScanner);
|
||||||
|
|
||||||
return new PdfDocument(log, inputBytes, version, crossReferenceTable, caching, pageFactory, catalog, information,
|
return new PdfDocument(log, inputBytes, version, crossReferenceTable, caching, pageFactory, catalog, information,
|
||||||
encryptionDictionary,
|
encryptionDictionary,
|
||||||
pdfScanner,
|
pdfScanner,
|
||||||
@@ -162,20 +162,10 @@
|
|||||||
private static (IndirectReference, DictionaryToken) ParseTrailer(CrossReferenceTable crossReferenceTable, bool isLenientParsing, IPdfTokenScanner pdfTokenScanner,
|
private static (IndirectReference, DictionaryToken) ParseTrailer(CrossReferenceTable crossReferenceTable, bool isLenientParsing, IPdfTokenScanner pdfTokenScanner,
|
||||||
out EncryptionDictionary encryptionDictionary)
|
out EncryptionDictionary encryptionDictionary)
|
||||||
{
|
{
|
||||||
encryptionDictionary = null;
|
encryptionDictionary = GetEncryptionDictionary(crossReferenceTable, pdfTokenScanner);
|
||||||
|
|
||||||
if (crossReferenceTable.Trailer.EncryptionToken != null)
|
|
||||||
{
|
|
||||||
if (!DirectObjectFinder.TryGet(crossReferenceTable.Trailer.EncryptionToken, pdfTokenScanner, out DictionaryToken encryptionDictionaryToken))
|
|
||||||
{
|
|
||||||
throw new PdfDocumentFormatException($"Unrecognized encryption token in trailer: {crossReferenceTable.Trailer.EncryptionToken}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
encryptionDictionary = EncryptionDictionaryFactory.Read(encryptionDictionaryToken, pdfTokenScanner);
|
|
||||||
}
|
|
||||||
|
|
||||||
var rootDictionary = DirectObjectFinder.Get<DictionaryToken>(crossReferenceTable.Trailer.Root, pdfTokenScanner);
|
var rootDictionary = DirectObjectFinder.Get<DictionaryToken>(crossReferenceTable.Trailer.Root, pdfTokenScanner);
|
||||||
|
|
||||||
if (!rootDictionary.ContainsKey(NameToken.Type) && isLenientParsing)
|
if (!rootDictionary.ContainsKey(NameToken.Type) && isLenientParsing)
|
||||||
{
|
{
|
||||||
rootDictionary = rootDictionary.With(NameToken.Type, NameToken.Catalog);
|
rootDictionary = rootDictionary.With(NameToken.Type, NameToken.Catalog);
|
||||||
@@ -183,5 +173,28 @@
|
|||||||
|
|
||||||
return (crossReferenceTable.Trailer.Root, rootDictionary);
|
return (crossReferenceTable.Trailer.Root, rootDictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static EncryptionDictionary GetEncryptionDictionary(CrossReferenceTable crossReferenceTable, IPdfTokenScanner pdfTokenScanner)
|
||||||
|
{
|
||||||
|
if (crossReferenceTable.Trailer.EncryptionToken == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!DirectObjectFinder.TryGet(crossReferenceTable.Trailer.EncryptionToken, pdfTokenScanner, out DictionaryToken encryptionDictionaryToken))
|
||||||
|
{
|
||||||
|
if (DirectObjectFinder.TryGet(crossReferenceTable.Trailer.EncryptionToken, pdfTokenScanner, out NullToken _))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new PdfDocumentFormatException($"Unrecognized encryption token in trailer: {crossReferenceTable.Trailer.EncryptionToken}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = EncryptionDictionaryFactory.Read(encryptionDictionaryToken, pdfTokenScanner);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user