diff --git a/src/UglyToad.PdfPig.Tests/Integration/LocalTests.cs b/src/UglyToad.PdfPig.Tests/Integration/LocalTests.cs
index 8a6b15c6..39a61e21 100644
--- a/src/UglyToad.PdfPig.Tests/Integration/LocalTests.cs
+++ b/src/UglyToad.PdfPig.Tests/Integration/LocalTests.cs
@@ -3,17 +3,17 @@
//using System;
//using System.Diagnostics;
//using System.IO;
- using Xunit;
+ //using Xunit;
///
/// A class for testing files which are not checked in to source control.
///
public class LocalTests
{
- [Fact]
- public void Tests()
- {
- // var files = new[]{ @"C:\Users\eliot\Downloads\Encrypted1.pdf" };
+ //[Fact]
+ //public void Tests()
+ //{
+ // var files = new[] { @"C:\Users\eliot\Downloads\Encrypted1.pdf" };
// foreach (var file in files)
// {
@@ -34,6 +34,6 @@
// throw new InvalidOperationException($"Error parsing: {Path.GetFileName(file)}.", ex);
// }
// }
- }
+ //}
}
}
diff --git a/src/UglyToad.PdfPig/AcroForms/AcroFormFactory.cs b/src/UglyToad.PdfPig/AcroForms/AcroFormFactory.cs
index 1ec71f5f..a88b5841 100644
--- a/src/UglyToad.PdfPig/AcroForms/AcroFormFactory.cs
+++ b/src/UglyToad.PdfPig/AcroForms/AcroFormFactory.cs
@@ -4,7 +4,6 @@
using System.Collections.Generic;
using System.Linq;
using Content;
- using Encryption;
using Exceptions;
using Fields;
using Filters;
@@ -21,13 +20,11 @@
{
private readonly IPdfTokenScanner tokenScanner;
private readonly IFilterProvider filterProvider;
- private readonly IEncryptionHandler encryptionHandler;
- public AcroFormFactory(IPdfTokenScanner tokenScanner, IFilterProvider filterProvider, IEncryptionHandler encryptionHandler)
+ public AcroFormFactory(IPdfTokenScanner tokenScanner, IFilterProvider filterProvider)
{
this.tokenScanner = tokenScanner ?? throw new ArgumentNullException(nameof(tokenScanner));
this.filterProvider = filterProvider ?? throw new ArgumentNullException(nameof(filterProvider));
- this.encryptionHandler = encryptionHandler ?? throw new ArgumentNullException(nameof(encryptionHandler));
}
///
@@ -215,7 +212,7 @@
}
else if (DirectObjectFinder.TryGet(textValueToken, tokenScanner, out StreamToken valueStreamToken))
{
- textValue = OtherEncodings.BytesAsLatin1String(valueStreamToken.Decode(filterProvider, encryptionHandler).ToArray());
+ textValue = OtherEncodings.BytesAsLatin1String(valueStreamToken.Decode(filterProvider).ToArray());
}
}
diff --git a/src/UglyToad.PdfPig/Encryption/EncryptionHandler.cs b/src/UglyToad.PdfPig/Encryption/EncryptionHandler.cs
index ad9dda11..d34e5dda 100644
--- a/src/UglyToad.PdfPig/Encryption/EncryptionHandler.cs
+++ b/src/UglyToad.PdfPig/Encryption/EncryptionHandler.cs
@@ -2,6 +2,7 @@
{
using System;
using System.Collections.Generic;
+ using System.Linq;
using System.Security.Cryptography;
using System.Text;
using CrossReference;
@@ -11,7 +12,7 @@
internal class EncryptionHandler : IEncryptionHandler
{
- private static readonly byte[] PaddingBytes =
+ private static readonly byte[] PaddingBytes =
{
0x28, 0xBF, 0x4E, 0x5E,
0x4E, 0x75, 0x8A, 0x41,
@@ -23,6 +24,8 @@
0x64, 0x53, 0x69, 0x7A
};
+ private readonly HashSet previouslyDecrypted = new HashSet();
+
[CanBeNull]
private readonly EncryptionDictionary encryptionDictionary;
@@ -40,7 +43,7 @@
{
this.encryptionDictionary = encryptionDictionary;
- documentIdBytes = trailerDictionary.Identifier != null && trailerDictionary.Identifier.Count == 2 ?
+ documentIdBytes = trailerDictionary.Identifier != null && trailerDictionary.Identifier.Count == 2 ?
OtherEncodings.StringAsLatin1Bytes(trailerDictionary.Identifier[0])
: EmptyArray.Instance;
this.password = password ?? string.Empty;
@@ -63,47 +66,114 @@
var passwordBytes = charset.GetBytes(this.password);
- var length = encryptionDictionary.EncryptionAlgorithmCode == EncryptionAlgorithmCode.Rc4OrAes40BitKey
- ? 5
+ var length = encryptionDictionary.EncryptionAlgorithmCode == EncryptionAlgorithmCode.Rc4OrAes40BitKey
+ ? 5
: encryptionDictionary.KeyLength.GetValueOrDefault() / 8;
- encryptionKey = CalculateKeyRevisions2To4(passwordBytes, ownerKey, (int) encryptionDictionary.UserAccessPermissions, encryptionDictionary.StandardSecurityHandlerRevision,
+ encryptionKey = CalculateKeyRevisions2To4(passwordBytes, ownerKey, (int)encryptionDictionary.UserAccessPermissions, encryptionDictionary.StandardSecurityHandlerRevision,
length, documentIdBytes, encryptionDictionary.EncryptMetadata);
- }
-
- public IReadOnlyList Decrypt(StreamToken stream)
- {
- if (encryptionDictionary == null)
- {
- return stream?.Data;
- }
- if (stream == null)
- {
- throw new ArgumentNullException(nameof(stream));
- }
-
- throw new NotImplementedException($"Encryption is not supported yet. Encryption used in document was: {encryptionDictionary.Dictionary}.");
+ useAes = false;
}
- public void Decrypt(IndirectReference reference, IToken token)
+ public IToken Decrypt(IndirectReference reference, IToken token)
{
- if (token is StreamToken stream)
+ if (token == null)
{
-
+ throw new ArgumentNullException(nameof(token));
}
- else if (token is StringToken stringToken)
- {
-
- }
- else if (token is DictionaryToken dictionary)
- {
-
- }
- else if (token is ArrayToken array)
- {
+
+ token = DecryptInternal(reference, token);
+ previouslyDecrypted.Add(reference);
+
+ return token;
+ }
+
+ private IToken DecryptInternal(IndirectReference reference, IToken token)
+ {
+ switch (token)
+ {
+ case StreamToken stream:
+ {
+ if (stream.StreamDictionary.TryGet(NameToken.Type, out NameToken typeName))
+ {
+ if (NameToken.Xref.Equals(typeName))
+ {
+ return token;
+ }
+
+ if (!encryptionDictionary.EncryptMetadata && NameToken.Metadata.Equals(typeName))
+ {
+ return token;
+ }
+
+ // TODO: check unencrypted metadata
+ }
+
+ var streamDictionary = (DictionaryToken)DecryptInternal(reference, stream.StreamDictionary);
+
+ var decrypted = DecryptData(stream.Data.ToArray(), reference);
+
+ token = new StreamToken(streamDictionary, decrypted);
+
+ break;
+ }
+ case StringToken stringToken:
+ {
+ var data = OtherEncodings.StringAsLatin1Bytes(stringToken.Data);
+
+ var decrypted = DecryptData(data, reference);
+
+ token = new StringToken(OtherEncodings.BytesAsLatin1String(decrypted));
+
+ break;
+ }
+ case DictionaryToken dictionary:
+ {
+ // PDFBOX-2936: avoid orphan /CF dictionaries found in US govt "I-" files
+ if (dictionary.TryGet(NameToken.Cf, out _))
+ {
+ return token;
+ }
+
+ var isSignatureDictionary = dictionary.TryGet(NameToken.Type, out NameToken typeName)
+ && (typeName.Equals(NameToken.Sig) || typeName.Equals(NameToken.DocTimeStamp));
+
+ foreach (var keyValuePair in dictionary.Data)
+ {
+ if (isSignatureDictionary && keyValuePair.Key == NameToken.Contents.Data)
+ {
+ continue;
+ }
+
+ if (keyValuePair.Value is StringToken || keyValuePair.Value is ArrayToken || keyValuePair.Value is DictionaryToken)
+ {
+ var inner = DecryptInternal(reference, keyValuePair.Value);
+ dictionary = dictionary.With(keyValuePair.Key, inner);
+ }
+ }
+
+ token = dictionary;
+
+ break;
+ }
+ case ArrayToken array:
+ {
+ var result = new IToken[array.Length];
+
+ for (var i = 0; i < array.Length; i++)
+ {
+ result[i] = DecryptInternal(reference, array.Data[i]);
+ }
+
+ token = new ArrayToken(result);
+
+ break;
+ }
}
+
+ return token;
}
private byte[] DecryptData(byte[] data, IndirectReference reference)
@@ -119,12 +189,12 @@
{
throw new NotImplementedException("Decryption for AES-128 not currently supported.");
}
-
+
return RC4.Encrypt(finalKey, data);
}
private byte[] GetObjectKey(IndirectReference reference)
- {
+ {
// 1. Get the object and generation number from the object
// 2. Treating the object and generation number as binary integers extend the
@@ -134,13 +204,13 @@
var finalKey = new byte[encryptionKey.Length + 5 + (useAes ? 4 : 0)];
Array.Copy(encryptionKey, finalKey, encryptionKey.Length);
- finalKey[encryptionKey.Length] = (byte) reference.ObjectNumber;
- finalKey[encryptionKey.Length + 1] = (byte) (reference.ObjectNumber >> 1);
- finalKey[encryptionKey.Length + 2] = (byte) (reference.ObjectNumber >> 2);
+ finalKey[encryptionKey.Length] = (byte)reference.ObjectNumber;
+ finalKey[encryptionKey.Length + 1] = (byte)(reference.ObjectNumber >> 8);
+ finalKey[encryptionKey.Length + 2] = (byte)(reference.ObjectNumber >> 16);
+
+ finalKey[encryptionKey.Length + 3] = (byte)reference.Generation;
+ finalKey[encryptionKey.Length + 4] = (byte)(reference.Generation >> 8);
- finalKey[encryptionKey.Length + 3] = (byte) reference.Generation;
- finalKey[encryptionKey.Length + 4] = (byte) (reference.Generation >> 1);
-
// 2. If using the AES algorithm extend the encryption key by 4 bytes by adding the value "sAlT".
if (useAes)
{
@@ -195,32 +265,28 @@
using (var md5 = MD5.Create())
{
// 2. Initialize the MD5 hash function and pass the result of step 1 as input to this function.
- var has = md5.ComputeHash(passwordFull);
+ UpdateMd5(md5, passwordFull);
// 3. Pass the value of the encryption dictionary's owner key entry to the MD5 hash function.
- var has1 = md5.ComputeHash(ownerKey);
+ UpdateMd5(md5, ownerKey);
// 4. Treat the value of the P entry as an unsigned 4-byte integer.
- var unsigned = (uint) permissions;
- var permissionsBytes = new []
- {
- (byte) (unsigned),
- (byte) (unsigned >> 8),
- (byte) (unsigned >> 16),
- (byte) (unsigned >> 24)
- };
+ var unsigned = (uint)permissions;
// 4. Pass these bytes to the MD5 hash function, low-order byte first.
- var has2 = md5.ComputeHash(permissionsBytes);
+ UpdateMd5(md5, new[] { (byte)(unsigned) });
+ UpdateMd5(md5, new[] { (byte)(unsigned >> 8) });
+ UpdateMd5(md5, new[] { (byte)(unsigned >> 16) });
+ UpdateMd5(md5, new[] { (byte)(unsigned >> 24) });
// 5. Pass the first element of the file's file identifier array to the hash.
- var has3 = md5.ComputeHash(documentId);
+ UpdateMd5(md5, documentId);
// 6. (Revision 4 or greater) If document metadata is not being encrypted, pass 4 bytes
// with the value 0xFFFFFFFF to the MD5 hash function.
if (revision >= 4)
{
- md5.ComputeHash(new byte[] {0xFF, 0xFF, 0xFF, 0xFF});
+ UpdateMd5(md5, new byte[] { 0xFF, 0xFF, 0xFF, 0xFF });
}
// 7. Do the following 50 times: Take the output from the previous MD5 hash and
@@ -235,11 +301,13 @@
for (var i = 0; i < 50; i++)
{
- md5.ComputeHash(input, 0, n);
+ UpdateMd5(md5, input.Take(n).ToArray());
input = md5.Hash;
}
}
+ md5.TransformFinalBlock(EmptyArray.Instance, 0, 0);
+
var result = new byte[length];
Array.Copy(md5.Hash, result, length);
@@ -248,6 +316,11 @@
}
}
+ private static void UpdateMd5(MD5 md5, byte[] data)
+ {
+ md5.TransformBlock(data, 0, data.Length, null, 0);
+ }
+
private static byte[] GetPaddedPassword(byte[] password)
{
if (password == null || password.Length == 0)
diff --git a/src/UglyToad.PdfPig/Encryption/IEncryptionHandler.cs b/src/UglyToad.PdfPig/Encryption/IEncryptionHandler.cs
index 84090a2b..70140628 100644
--- a/src/UglyToad.PdfPig/Encryption/IEncryptionHandler.cs
+++ b/src/UglyToad.PdfPig/Encryption/IEncryptionHandler.cs
@@ -1,6 +1,5 @@
namespace UglyToad.PdfPig.Encryption
{
- using System.Collections.Generic;
using Tokens;
///
@@ -8,9 +7,6 @@
///
internal interface IEncryptionHandler
{
- ///
- /// Decrypt the contents of the stream if encryption is applied.
- ///
- IReadOnlyList Decrypt(StreamToken stream);
+ IToken Decrypt(IndirectReference reference, IToken token);
}
}
diff --git a/src/UglyToad.PdfPig/Encryption/NoOpEncryptionHandler.cs b/src/UglyToad.PdfPig/Encryption/NoOpEncryptionHandler.cs
index 092edd36..7befe211 100644
--- a/src/UglyToad.PdfPig/Encryption/NoOpEncryptionHandler.cs
+++ b/src/UglyToad.PdfPig/Encryption/NoOpEncryptionHandler.cs
@@ -1,6 +1,5 @@
namespace UglyToad.PdfPig.Encryption
{
- using System.Collections.Generic;
using Tokens;
internal class NoOpEncryptionHandler : IEncryptionHandler
@@ -11,9 +10,9 @@
{
}
- public IReadOnlyList Decrypt(StreamToken stream)
+ public IToken Decrypt(IndirectReference reference, IToken token)
{
- return stream.Data;
+ return token;
}
}
}
\ No newline at end of file
diff --git a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/TrueTypeFontHandler.cs b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/TrueTypeFontHandler.cs
index d7867712..12776b7b 100644
--- a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/TrueTypeFontHandler.cs
+++ b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/TrueTypeFontHandler.cs
@@ -4,7 +4,6 @@
using SystemFonts;
using Cmap;
using Encodings;
- using Encryption;
using Exceptions;
using Filters;
using IO;
@@ -23,15 +22,13 @@
private readonly ILog log;
private readonly IPdfTokenScanner pdfScanner;
private readonly IFilterProvider filterProvider;
- private readonly IEncryptionHandler encryptionHandler;
private readonly CMapCache cMapCache;
private readonly FontDescriptorFactory fontDescriptorFactory;
private readonly TrueTypeFontParser trueTypeFontParser;
private readonly IEncodingReader encodingReader;
private readonly ISystemFontFinder systemFontFinder;
- public TrueTypeFontHandler(ILog log, IPdfTokenScanner pdfScanner, IFilterProvider filterProvider,
- IEncryptionHandler encryptionHandler,
+ public TrueTypeFontHandler(ILog log, IPdfTokenScanner pdfScanner, IFilterProvider filterProvider,
CMapCache cMapCache,
FontDescriptorFactory fontDescriptorFactory,
TrueTypeFontParser trueTypeFontParser,
@@ -40,7 +37,6 @@
{
this.log = log;
this.filterProvider = filterProvider;
- this.encryptionHandler = encryptionHandler;
this.cMapCache = cMapCache;
this.fontDescriptorFactory = fontDescriptorFactory;
this.trueTypeFontParser = trueTypeFontParser;
@@ -89,7 +85,7 @@
{
var toUnicode = DirectObjectFinder.Get(toUnicodeObj, pdfScanner);
- var decodedUnicodeCMap = toUnicode.Decode(filterProvider, encryptionHandler);
+ var decodedUnicodeCMap = toUnicode.Decode(filterProvider);
if (decodedUnicodeCMap != null)
{
@@ -129,7 +125,7 @@
var fontFileStream = DirectObjectFinder.Get(descriptor.FontFile.ObjectKey, pdfScanner);
- var fontFile = fontFileStream.Decode(filterProvider, encryptionHandler);
+ var fontFile = fontFileStream.Decode(filterProvider);
var font = trueTypeFontParser.Parse(new TrueTypeDataBytes(new ByteArrayInputBytes(fontFile)));
diff --git a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type0FontHandler.cs b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type0FontHandler.cs
index 329efe73..89c27fec 100644
--- a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type0FontHandler.cs
+++ b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type0FontHandler.cs
@@ -4,7 +4,6 @@
using CidFonts;
using Cmap;
using Composite;
- using Encryption;
using Exceptions;
using Filters;
using IO;
@@ -19,17 +18,14 @@
private readonly CidFontFactory cidFontFactory;
private readonly CMapCache cMapCache;
private readonly IFilterProvider filterProvider;
- private readonly IEncryptionHandler encryptionHandler;
private readonly IPdfTokenScanner scanner;
public Type0FontHandler(CidFontFactory cidFontFactory, CMapCache cMapCache, IFilterProvider filterProvider,
- IEncryptionHandler encryptionHandler,
IPdfTokenScanner scanner)
{
this.cidFontFactory = cidFontFactory;
this.cMapCache = cMapCache;
this.filterProvider = filterProvider;
- this.encryptionHandler = encryptionHandler;
this.scanner = scanner;
}
@@ -72,7 +68,7 @@
var toUnicode = DirectObjectFinder.Get(toUnicodeValue, scanner);
- var decodedUnicodeCMap = toUnicode?.Decode(filterProvider, encryptionHandler);
+ var decodedUnicodeCMap = toUnicode?.Decode(filterProvider);
if (decodedUnicodeCMap != null)
{
@@ -151,7 +147,7 @@
}
else if (value is StreamToken stream)
{
- var decoded = stream.Decode(filterProvider, encryptionHandler);
+ var decoded = stream.Decode(filterProvider);
var cmap = cMapCache.Parse(new ByteArrayInputBytes(decoded), false);
diff --git a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type1FontHandler.cs b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type1FontHandler.cs
index 16b6352f..7904b24d 100644
--- a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type1FontHandler.cs
+++ b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type1FontHandler.cs
@@ -1,10 +1,8 @@
namespace UglyToad.PdfPig.Fonts.Parser.Handlers
{
- using System.Linq;
using Cmap;
using CompactFontFormat;
using Encodings;
- using Encryption;
using Exceptions;
using Filters;
using IO;
@@ -22,14 +20,12 @@
private readonly IPdfTokenScanner pdfScanner;
private readonly CMapCache cMapCache;
private readonly IFilterProvider filterProvider;
- private readonly IEncryptionHandler encryptionHandler;
private readonly FontDescriptorFactory fontDescriptorFactory;
private readonly IEncodingReader encodingReader;
private readonly Type1FontParser type1FontParser;
private readonly CompactFontFormatParser compactFontFormatParser;
public Type1FontHandler(IPdfTokenScanner pdfScanner, CMapCache cMapCache, IFilterProvider filterProvider,
- IEncryptionHandler encryptionHandler,
FontDescriptorFactory fontDescriptorFactory,
IEncodingReader encodingReader,
Type1FontParser type1FontParser,
@@ -38,7 +34,6 @@
this.pdfScanner = pdfScanner;
this.cMapCache = cMapCache;
this.filterProvider = filterProvider;
- this.encryptionHandler = encryptionHandler;
this.fontDescriptorFactory = fontDescriptorFactory;
this.encodingReader = encodingReader;
this.type1FontParser = type1FontParser;
@@ -93,7 +88,7 @@
{
var toUnicode = DirectObjectFinder.Get(toUnicodeObj, pdfScanner);
- var decodedUnicodeCMap = toUnicode?.Decode(filterProvider, encryptionHandler);
+ var decodedUnicodeCMap = toUnicode?.Decode(filterProvider);
if (decodedUnicodeCMap != null)
{
@@ -130,7 +125,7 @@
return null;
}
- var bytes = stream.Decode(filterProvider, encryptionHandler);
+ var bytes = stream.Decode(filterProvider);
// We have a Compact Font Format font rather than an Adobe Type 1 Font.
if (stream.StreamDictionary.TryGet(NameToken.Subtype, out NameToken subTypeName)
diff --git a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type3FontHandler.cs b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type3FontHandler.cs
index d52f8d7e..a0cffbd3 100644
--- a/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type3FontHandler.cs
+++ b/src/UglyToad.PdfPig/Fonts/Parser/Handlers/Type3FontHandler.cs
@@ -3,7 +3,6 @@
using Cmap;
using Core;
using Encodings;
- using Encryption;
using Exceptions;
using Filters;
using Geometry;
@@ -18,17 +17,14 @@
{
private readonly CMapCache cMapCache;
private readonly IFilterProvider filterProvider;
- private readonly IEncryptionHandler encryptionHandler;
private readonly IEncodingReader encodingReader;
private readonly IPdfTokenScanner scanner;
public Type3FontHandler(IPdfTokenScanner scanner, CMapCache cMapCache, IFilterProvider filterProvider,
- IEncryptionHandler encryptionHandler,
IEncodingReader encodingReader)
{
this.cMapCache = cMapCache;
this.filterProvider = filterProvider;
- this.encryptionHandler = encryptionHandler;
this.encodingReader = encodingReader;
this.scanner = scanner;
}
@@ -50,7 +46,7 @@
{
var toUnicode = DirectObjectFinder.Get(toUnicodeObj, scanner);
- var decodedUnicodeCMap = toUnicode?.Decode(filterProvider, encryptionHandler);
+ var decodedUnicodeCMap = toUnicode?.Decode(filterProvider);
if (decodedUnicodeCMap != null)
{
diff --git a/src/UglyToad.PdfPig/Fonts/Parser/Parts/CidFontFactory.cs b/src/UglyToad.PdfPig/Fonts/Parser/Parts/CidFontFactory.cs
index eca91c3e..e05fda32 100644
--- a/src/UglyToad.PdfPig/Fonts/Parser/Parts/CidFontFactory.cs
+++ b/src/UglyToad.PdfPig/Fonts/Parser/Parts/CidFontFactory.cs
@@ -4,7 +4,6 @@
using System.Collections.Generic;
using CidFonts;
using CompactFontFormat;
- using Encryption;
using Exceptions;
using Filters;
using Geometry;
@@ -23,21 +22,18 @@
private readonly TrueTypeFontParser trueTypeFontParser;
private readonly CompactFontFormatParser compactFontFormatParser;
private readonly IFilterProvider filterProvider;
- private readonly IEncryptionHandler encryptionHandler;
private readonly IPdfTokenScanner pdfScanner;
public CidFontFactory(IPdfTokenScanner pdfScanner, FontDescriptorFactory descriptorFactory,
TrueTypeFontParser trueTypeFontParser,
CompactFontFormatParser compactFontFormatParser,
- IFilterProvider filterProvider,
- IEncryptionHandler encryptionHandler)
+ IFilterProvider filterProvider)
{
this.pdfScanner = pdfScanner;
this.descriptorFactory = descriptorFactory;
this.trueTypeFontParser = trueTypeFontParser;
this.compactFontFormatParser = compactFontFormatParser;
this.filterProvider = filterProvider;
- this.encryptionHandler = encryptionHandler;
}
public ICidFont Generate(DictionaryToken dictionary, bool isLenientParsing)
@@ -109,7 +105,7 @@
return null;
}
- var fontFile = fontFileStream.Decode(filterProvider, encryptionHandler);
+ var fontFile = fontFileStream.Decode(filterProvider);
switch (descriptor.FontFile.FileType)
{
@@ -130,7 +126,7 @@
if (subtypeName == NameToken.CidFontType0C)
{
- var bytes = str.Decode(filterProvider, encryptionHandler);
+ var bytes = str.Decode(filterProvider);
var font = compactFontFormatParser.Parse(new CompactFontFormatData(bytes));
return font;
}
@@ -302,7 +298,7 @@
var stream = DirectObjectFinder.Get(entry, pdfScanner);
- var bytes = stream.Decode(filterProvider, encryptionHandler);
+ var bytes = stream.Decode(filterProvider);
return new CharacterIdentifierToGlyphIndexMap(bytes);
}
diff --git a/src/UglyToad.PdfPig/Parser/PageFactory.cs b/src/UglyToad.PdfPig/Parser/PageFactory.cs
index d51969d2..7bebcc75 100644
--- a/src/UglyToad.PdfPig/Parser/PageFactory.cs
+++ b/src/UglyToad.PdfPig/Parser/PageFactory.cs
@@ -22,20 +22,17 @@
private readonly IPdfTokenScanner pdfScanner;
private readonly IResourceStore resourceStore;
private readonly IFilterProvider filterProvider;
- private readonly IEncryptionHandler encryptionHandler;
private readonly IPageContentParser pageContentParser;
private readonly XObjectFactory xObjectFactory;
private readonly ILog log;
public PageFactory(IPdfTokenScanner pdfScanner, IResourceStore resourceStore, IFilterProvider filterProvider,
- IEncryptionHandler encryptionHandler,
IPageContentParser pageContentParser,
XObjectFactory xObjectFactory,
ILog log)
{
this.resourceStore = resourceStore;
this.filterProvider = filterProvider;
- this.encryptionHandler = encryptionHandler;
this.pageContentParser = pageContentParser;
this.xObjectFactory = xObjectFactory;
this.log = log;
@@ -88,7 +85,7 @@
throw new InvalidOperationException($"Could not find the contents for object {obj}.");
}
- bytes.AddRange(contentStream.Decode(filterProvider, encryptionHandler));
+ bytes.AddRange(contentStream.Decode(filterProvider));
}
content = GetContent(bytes, cropBox, userSpaceUnit, isLenientParsing);
@@ -102,7 +99,7 @@
throw new InvalidOperationException("Failed to parse the content for the page: " + number);
}
- var bytes = contentStream.Decode(filterProvider, encryptionHandler);
+ var bytes = contentStream.Decode(filterProvider);
content = GetContent(bytes, cropBox, userSpaceUnit, isLenientParsing);
}
diff --git a/src/UglyToad.PdfPig/Parser/Parts/CrossReference/CrossReferenceStreamParser.cs b/src/UglyToad.PdfPig/Parser/Parts/CrossReference/CrossReferenceStreamParser.cs
index 9a18689a..c00b94aa 100644
--- a/src/UglyToad.PdfPig/Parser/Parts/CrossReference/CrossReferenceStreamParser.cs
+++ b/src/UglyToad.PdfPig/Parser/Parts/CrossReference/CrossReferenceStreamParser.cs
@@ -1,7 +1,6 @@
namespace UglyToad.PdfPig.Parser.Parts.CrossReference
{
using System.Collections.Generic;
- using Encryption;
using Exceptions;
using Filters;
using PdfPig.CrossReference;
@@ -22,7 +21,7 @@
///
public CrossReferenceTablePart Parse(long streamOffset, StreamToken stream)
{
- var decoded = stream.Decode(filterProvider, NoOpEncryptionHandler.Instance);
+ var decoded = stream.Decode(filterProvider);
var fieldSizes = new CrossReferenceStreamFieldSize(stream.StreamDictionary);
diff --git a/src/UglyToad.PdfPig/Parser/PdfDocumentFactory.cs b/src/UglyToad.PdfPig/Parser/PdfDocumentFactory.cs
index d44d3e51..72dae092 100644
--- a/src/UglyToad.PdfPig/Parser/PdfDocumentFactory.cs
+++ b/src/UglyToad.PdfPig/Parser/PdfDocumentFactory.cs
@@ -107,25 +107,25 @@
var rootDictionary = ParseTrailer(crossReferenceTable, isLenientParsing, pdfScanner, out var encryptionDictionary);
- var encryptionHandler = new EncryptionHandler(encryptionDictionary, crossReferenceTable.Trailer, string.Empty);
+ var encryptionHandler = encryptionDictionary != null ? (IEncryptionHandler)new EncryptionHandler(encryptionDictionary, crossReferenceTable.Trailer, string.Empty)
+ : NoOpEncryptionHandler.Instance;
pdfScanner.UpdateEncryptionHandler(encryptionHandler);
- var cidFontFactory = new CidFontFactory(pdfScanner, fontDescriptorFactory, trueTypeFontParser, compactFontFormatParser, filterProvider, encryptionHandler);
+ var cidFontFactory = new CidFontFactory(pdfScanner, fontDescriptorFactory, trueTypeFontParser, compactFontFormatParser, filterProvider);
var encodingReader = new EncodingReader(pdfScanner);
var fontFactory = new FontFactory(log, new Type0FontHandler(cidFontFactory,
cMapCache,
- filterProvider, encryptionHandler, pdfScanner),
- new TrueTypeFontHandler(log, pdfScanner, filterProvider, encryptionHandler, cMapCache, fontDescriptorFactory, trueTypeFontParser, encodingReader, new SystemFontFinder(new TrueTypeFontParser())),
- new Type1FontHandler(pdfScanner, cMapCache, filterProvider, encryptionHandler, fontDescriptorFactory, encodingReader,
+ filterProvider, pdfScanner),
+ new TrueTypeFontHandler(log, pdfScanner, filterProvider, cMapCache, fontDescriptorFactory, trueTypeFontParser, encodingReader, new SystemFontFinder(new TrueTypeFontParser())),
+ new Type1FontHandler(pdfScanner, cMapCache, filterProvider, fontDescriptorFactory, encodingReader,
new Type1FontParser(new Type1EncryptedPortionParser()), compactFontFormatParser),
- new Type3FontHandler(pdfScanner, cMapCache, filterProvider, encryptionHandler, encodingReader));
+ new Type3FontHandler(pdfScanner, cMapCache, filterProvider, encodingReader));
var resourceContainer = new ResourceContainer(pdfScanner, fontFactory);
var pageFactory = new PageFactory(pdfScanner, resourceContainer, filterProvider,
- encryptionHandler,
new PageContentParser(new ReflectionGraphicsStateOperationFactory()),
new XObjectFactory(), log);
var informationFactory = new DocumentInformationFactory();
@@ -136,7 +136,7 @@
var caching = new ParsingCachingProviders(bruteForceSearcher, resourceContainer);
- var acroFormFactory = new AcroFormFactory(pdfScanner, filterProvider, encryptionHandler);
+ var acroFormFactory = new AcroFormFactory(pdfScanner, filterProvider);
return new PdfDocument(log, inputBytes, version, crossReferenceTable, isLenientParsing, caching, pageFactory, catalog, information,
encryptionDictionary,
diff --git a/src/UglyToad.PdfPig/Tokenization/Scanner/PdfTokenScanner.cs b/src/UglyToad.PdfPig/Tokenization/Scanner/PdfTokenScanner.cs
index 27ef20eb..c0fcfb19 100644
--- a/src/UglyToad.PdfPig/Tokenization/Scanner/PdfTokenScanner.cs
+++ b/src/UglyToad.PdfPig/Tokenization/Scanner/PdfTokenScanner.cs
@@ -158,6 +158,8 @@
token = readTokens[readTokens.Count - 1];
}
+ token = encryptionHandler.Decrypt(reference, token);
+
CurrentToken = new ObjectToken(startPosition, reference, token);
objectLocationProvider.UpdateOffset(reference, startPosition);
@@ -537,7 +539,7 @@
}
// Read the N integers
- var bytes = new ByteArrayInputBytes(stream.Decode(filterProvider, encryptionHandler));
+ var bytes = new ByteArrayInputBytes(stream.Decode(filterProvider));
var scanner = new CoreTokenScanner(bytes);
diff --git a/src/UglyToad.PdfPig/Tokens/StreamToken.cs b/src/UglyToad.PdfPig/Tokens/StreamToken.cs
index 40f98ebc..8a9ad5d9 100644
--- a/src/UglyToad.PdfPig/Tokens/StreamToken.cs
+++ b/src/UglyToad.PdfPig/Tokens/StreamToken.cs
@@ -2,7 +2,6 @@
{
using System;
using System.Collections.Generic;
- using Encryption;
using Filters;
using Util.JetBrains.Annotations;
@@ -39,7 +38,7 @@
Data = data ?? throw new ArgumentNullException(nameof(data));
}
- internal IReadOnlyList Decode(IFilterProvider filterProvider, IEncryptionHandler encryptionHandler)
+ internal IReadOnlyList Decode(IFilterProvider filterProvider)
{
lock (lockObject)
{
@@ -50,7 +49,7 @@
var filters = filterProvider.GetFilters(StreamDictionary);
- var transform = encryptionHandler.Decrypt(this);
+ var transform = Data;
for (var i = 0; i < filters.Count; i++)
{
transform = filters[i].Decode(transform, StreamDictionary, i);