コード例 #1
0
ファイル: PdfDocumentFactory.cs プロジェクト: AnilAwadh/Pdf
        private static CosBase ParseTrailer(IRandomAccessRead reader, CrossReferenceTable crossReferenceTable,
                                            DynamicParser dynamicParser, BruteForceSearcher bruteForceSearcher, CosObjectPool pool, bool isLenientParsing)
        {
            foreach (var value in crossReferenceTable.Dictionary.Values)
            {
                if (value is CosObject temporaryObject)
                {
                    // Loads these objects into the object pool for access later.
                    dynamicParser.Parse(reader, temporaryObject, pool, crossReferenceTable, bruteForceSearcher,
                                        isLenientParsing, false);
                }
            }

            CosObject root = (CosObject)crossReferenceTable.Dictionary.GetItemOrDefault(CosName.ROOT);

            if (root == null)
            {
                throw new InvalidOperationException("Missing root object specification in trailer.");
            }

            var rootObject = dynamicParser.Parse(reader, root, pool, crossReferenceTable, bruteForceSearcher,
                                                 isLenientParsing, false);

            return(rootObject);
        }
コード例 #2
0
        public void ReaderEscapesUnexpectedGenerationNumber()
        {
            const string s = @"%PDF-2.0
abcdefghijklmnop

1 0 obj
256
endobj

16-0 obj

5 0 obj
<< /IsEmpty false >>
endobj";

            var bytes = new ByteArrayInputBytes(OtherEncodings.StringAsLatin1Bytes(s));

            var locations = BruteForceSearcher.GetObjectLocations(bytes);

            Assert.Equal(2, locations.Count);

            var expectedLocations = new long[]
            {
                s.IndexOf("1 0 obj", StringComparison.OrdinalIgnoreCase),
                s.IndexOf("5 0 obj", StringComparison.OrdinalIgnoreCase)
            };

            Assert.Equal(expectedLocations, locations.Values);
        }
コード例 #3
0
        public bool TryGetOffset(IndirectReference reference, out long offset)
        {
            if (!loadedFromTable)
            {
                var table = crossReferenceTable.Invoke();

                if (table != null)
                {
                    foreach (var objectOffset in table.ObjectOffsets)
                    {
                        offsets[objectOffset.Key] = objectOffset.Value;
                    }

                    loadedFromTable = true;
                }
            }

            if (offsets.TryGetValue(reference, out offset))
            {
                return(true);
            }

            if (bruteForcedOffsets == null)
            {
                bruteForcedOffsets = BruteForceSearcher.GetObjectLocations(bytes);
            }

            return(bruteForcedOffsets.TryGetValue(reference, out offset));
        }
コード例 #4
0
        public void BruteForceSearcherFileOffsetsCorrect()
        {
            using (var fs = File.OpenRead(IntegrationHelpers.GetDocumentPath("Single Page Simple - from inkscape.pdf")))
            {
                var bytes    = new StreamInputBytes(fs);
                var searcher = new BruteForceSearcher(bytes);

                var locations = searcher.GetObjectLocations();

                Assert.Equal(13, locations.Count);

                Assert.Equal(6183, locations[new IndirectReference(1, 0)]);
                Assert.Equal(244, locations[new IndirectReference(2, 0)]);
                Assert.Equal(15, locations[new IndirectReference(3, 0)]);
                Assert.Equal(222, locations[new IndirectReference(4, 0)]);
                Assert.Equal(5766, locations[new IndirectReference(5, 0)]);
                Assert.Equal(353, locations[new IndirectReference(6, 0)]);
                Assert.Equal(581, locations[new IndirectReference(7, 0)]);
                Assert.Equal(5068, locations[new IndirectReference(8, 0)]);
                Assert.Equal(5091, locations[new IndirectReference(9, 0)]);

                var s = GetStringAt(bytes, locations[new IndirectReference(3, 0)]);
                Assert.StartsWith("3 0 obj", s);
            }
        }
コード例 #5
0
        public void BruteForceSearcherFileOffsetsCorrectOpenOffice()
        {
            var bytes = new ByteArrayInputBytes(File.ReadAllBytes(IntegrationHelpers.GetDocumentPath("Single Page Simple - from open office.pdf")));

            var locations = BruteForceSearcher.GetObjectLocations(bytes);

            Assert.Equal(13, locations.Count);

            Assert.Equal(17, locations[new IndirectReference(1, 0)]);
            Assert.Equal(249, locations[new IndirectReference(2, 0)]);
            Assert.Equal(14291, locations[new IndirectReference(3, 0)]);
            Assert.Equal(275, locations[new IndirectReference(4, 0)]);
            Assert.Equal(382, locations[new IndirectReference(5, 0)]);
            Assert.Equal(13283, locations[new IndirectReference(6, 0)]);
            Assert.Equal(13309, locations[new IndirectReference(7, 0)]);
            Assert.Equal(13556, locations[new IndirectReference(8, 0)]);
            Assert.Equal(13926, locations[new IndirectReference(9, 0)]);
            Assert.Equal(14183, locations[new IndirectReference(10, 0)]);
            Assert.Equal(14224, locations[new IndirectReference(11, 0)]);
            Assert.Equal(14428, locations[new IndirectReference(12, 0)]);
            Assert.Equal(14488, locations[new IndirectReference(13, 0)]);

            var s = GetStringAt(bytes, locations[new IndirectReference(12, 0)]);

            Assert.StartsWith("12 0 obj", s);
        }
コード例 #6
0
        public void ReaderEscapesUnexpectedObject()
        {
            const string s = @"%PDF-1.7
abcd

1 0 obj
<< /Type /Any >>

endobj

%AZ 0 obj
11 0 obj
769
endobj

%%EOF";

            var bytes = new ByteArrayInputBytes(OtherEncodings.StringAsLatin1Bytes(s));

            var locations = BruteForceSearcher.GetObjectLocations(bytes);

            Assert.Equal(2, locations.Count);

            var expectedLocations = new long[]
            {
                s.IndexOf("1 0 obj", StringComparison.OrdinalIgnoreCase),
                s.IndexOf("11 0 obj", StringComparison.OrdinalIgnoreCase)
            };

            Assert.Equal(expectedLocations, locations.Values);
        }
コード例 #7
0
ファイル: DynamicParser.cs プロジェクト: AnilAwadh/Pdf
        public CosBase Parse(IRandomAccessRead reader, long objectNumber, int objectGeneration,
                             CosObjectPool pool, CrossReferenceTable crossReferenceTable,
                             BruteForceSearcher bruteForceSearcher,
                             bool isLenient,
                             bool requireExistingObject)
        {
            if (pool == null)
            {
                throw new ArgumentNullException(nameof(pool));
            }

            var key = new CosObjectKey(objectNumber, objectGeneration);

            var pdfObject = pool.GetOrCreateDefault(key);

            if (pdfObject.GetObject() != null)
            {
                return(pdfObject.GetObject());
            }

            if (crossReferenceTable == null)
            {
                throw new ArgumentNullException(nameof(crossReferenceTable));
            }

            var offsetOrStreamNumber = TryGet(key, crossReferenceTable.ObjectOffsets);

            if (requireExistingObject && (offsetOrStreamNumber == null || offsetOrStreamNumber <= 0))
            {
                throw new InvalidOperationException("Object must be defined and not compressed: " + key);
            }

            if (isLenient && offsetOrStreamNumber == null)
            {
                var locations = bruteForceSearcher.GetObjectLocations();

                offsetOrStreamNumber = TryGet(key, locations);

                if (offsetOrStreamNumber != null)
                {
                    crossReferenceTable.UpdateOffset(key, offsetOrStreamNumber.Value);
                }
            }

            if (offsetOrStreamNumber == null)
            {
                return(CosNull.Null);
            }

            var isCompressedStreamObject = offsetOrStreamNumber <= 0;

            if (!isCompressedStreamObject)
            {
                return(ParseObjectFromFile(offsetOrStreamNumber.Value, reader, key, pool, isLenient));
            }

            return(ParseCompressedStreamObject(reader, -offsetOrStreamNumber.Value, objectNumber, pool, crossReferenceTable, bruteForceSearcher, isLenient));
        }
コード例 #8
0
        public void BruteForceSearcherCorrectlyFindsAllObjectsWhenOffset()
        {
            var input = new ByteArrayInputBytes(OtherEncodings.StringAsLatin1Bytes(TestData));

            input.Seek(593);

            var locations = BruteForceSearcher.GetObjectLocations(input);

            Assert.Equal(TestDataOffsets, locations.Values);
        }
コード例 #9
0
        public void SearcherFindsCorrectObjects()
        {
            var input = new ByteArrayInputBytes(OtherEncodings.StringAsLatin1Bytes(TestData));

            var locations = BruteForceSearcher.GetObjectLocations(input);

            Assert.Equal(4, locations.Count);

            Assert.Equal(TestDataOffsets, locations.Values);
        }
コード例 #10
0
ファイル: DynamicParser.cs プロジェクト: AnilAwadh/Pdf
        public CosBase Parse(IRandomAccessRead reader, CosObject obj, CosObjectPool pool,
                             CrossReferenceTable crossReferenceTable, BruteForceSearcher bruteForceSearcher, bool isLenient, bool requireExistingObject)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            return(Parse(reader, obj.GetObjectNumber(), obj.GetGenerationNumber(), pool,
                         crossReferenceTable, bruteForceSearcher, isLenient, requireExistingObject));
        }
コード例 #11
0
 public PdfObjectParser(ILog log, CosBaseParser baseParser, CosStreamParser streamParser, CrossReferenceTable crossReferenceTable,
                        BruteForceSearcher bruteForceSearcher,
                        CosObjectPool objectPool,
                        ObjectStreamParser objectStreamParser)
 {
     this.log                 = log ?? new NoOpLog();
     this.baseParser          = baseParser ?? throw new ArgumentNullException(nameof(baseParser));
     this.streamParser        = streamParser ?? throw new ArgumentNullException(nameof(streamParser));
     this.crossReferenceTable = crossReferenceTable ?? throw new ArgumentNullException(nameof(crossReferenceTable));
     this.bruteForceSearcher  = bruteForceSearcher ?? throw new ArgumentNullException(nameof(bruteForceSearcher));
     this.objectPool          = objectPool ?? throw new ArgumentNullException(nameof(objectPool));
     this.objectStreamParser  = objectStreamParser ?? throw new ArgumentNullException(nameof(objectStreamParser));
 }
コード例 #12
0
        public void ReaderOnlyCallsOnce()
        {
            var reader = StringBytesTestConverter.Convert(TestData, false);

            var locations = BruteForceSearcher.GetObjectLocations(reader.Bytes);

            Assert.Equal(4, locations.Count);

            var newLocations = BruteForceSearcher.GetObjectLocations(reader.Bytes);

            Assert.Equal(4, locations.Count);

            foreach (var keyValuePair in locations)
            {
                Assert.Contains(newLocations.Keys, x => x.Equals(keyValuePair.Key));
            }
        }
コード例 #13
0
        public void SearcherFindsCorrectObjects()
        {
            var input = new ByteArrayInputBytes(OtherEncodings.StringAsLatin1Bytes(TestData));

            var searcher = new BruteForceSearcher(input);

            var locations = searcher.GetObjectLocations();

            Assert.Equal(4, locations.Count);

            Assert.Equal(locations.Values, new long[]
            {
                TestData.IndexOf("2 17 obj", StringComparison.OrdinalIgnoreCase),
                TestData.IndexOf("3 0 obj", StringComparison.OrdinalIgnoreCase),
                TestData.IndexOf("4 0 obj", StringComparison.OrdinalIgnoreCase),
                TestData.IndexOf("5 0 obj", StringComparison.OrdinalIgnoreCase)
            });
        }
コード例 #14
0
        public void SearcherFindsCorrectObjects()
        {
            var bytes = OtherEncodings.StringAsLatin1Bytes(TestData);

            var reader = new RandomAccessBuffer(bytes);

            var searcher = new BruteForceSearcher(reader);

            var locations = searcher.GetObjectLocations();

            Assert.Equal(4, locations.Count);

            Assert.Equal(locations.Values, new long[]
            {
                TestData.IndexOf("2 0 obj", StringComparison.OrdinalIgnoreCase),
                TestData.IndexOf("3 0 obj", StringComparison.OrdinalIgnoreCase),
                TestData.IndexOf("4 0 obj", StringComparison.OrdinalIgnoreCase),
                TestData.IndexOf("5 0 obj", StringComparison.OrdinalIgnoreCase)
            });
        }
コード例 #15
0
        /// <summary>
        /// Check that the offsets in the cross reference are correct.
        /// </summary>
        public static bool ValidateCrossReferenceOffsets(IInputBytes bytes, CrossReferenceTable crossReferenceTable, ILog log,
                                                         out IReadOnlyDictionary <IndirectReference, long> actualOffsets)
        {
            actualOffsets = crossReferenceTable.ObjectOffsets;

            if (ValidateXrefOffsets(bytes, crossReferenceTable.ObjectOffsets, log))
            {
                return(true);
            }

            var builderOffsets = new Dictionary <IndirectReference, long>();

            var bruteForceOffsets = BruteForceSearcher.GetObjectLocations(bytes);

            if (bruteForceOffsets.Count > 0)
            {
                // find all object streams
                foreach (var entry in crossReferenceTable.ObjectOffsets)
                {
                    var offset = entry.Value;
                    if (offset < 0)
                    {
                        // Trust stream offsets for now.
                        // TODO: more validation of streams.
                        builderOffsets[entry.Key] = entry.Value;
                    }

                    foreach (var item in bruteForceOffsets)
                    {
                        builderOffsets[item.Key] = item.Value;
                    }
                }

                actualOffsets = builderOffsets;
            }

            return(false);
        }
コード例 #16
0
        public void ReaderOnlyCallsOnce()
        {
            var bytes = OtherEncodings.StringAsLatin1Bytes(TestData);

            var reader = new ThrowingReader(new RandomAccessBuffer(bytes));

            var searcher = new BruteForceSearcher(reader);

            var locations = searcher.GetObjectLocations();

            Assert.Equal(4, locations.Count);

            reader.Throw = true;

            var newLocations = searcher.GetObjectLocations();

            Assert.Equal(4, locations.Count);

            foreach (var keyValuePair in locations)
            {
                Assert.Contains(newLocations.Keys, x => ReferenceEquals(x, keyValuePair.Key));
            }
        }
コード例 #17
0
ファイル: PdfDocumentFactory.cs プロジェクト: AnilAwadh/Pdf
        private static PdfDocument OpenDocument(IRandomAccessRead reader, IInputBytes inputBytes, ISeekableTokenScanner scanner, IContainer container, bool isLenientParsing)
        {
            var log = container.Get <ILog>();

            var version = container.Get <FileHeaderParser>().Parse(scanner, isLenientParsing);

            var crossReferenceOffset = container.Get <FileTrailerParser>().GetFirstCrossReferenceOffset(inputBytes, scanner, isLenientParsing);

            var pool = new CosObjectPool();

            // TODO: make this use the scanner.
            var validator = new CrossReferenceOffsetValidator(new XrefOffsetValidator(log, reader, container.Get <CosDictionaryParser>(),
                                                                                      container.Get <CosBaseParser>(), pool));

            crossReferenceOffset = validator.Validate(crossReferenceOffset, isLenientParsing);

            var crossReferenceTable = container.Get <CrossReferenceParser>()
                                      .Parse(reader, isLenientParsing, crossReferenceOffset, pool);

            container.Get <CrossReferenceParser>().ParseNew(crossReferenceOffset, scanner, isLenientParsing);

            var filterProvider     = container.Get <IFilterProvider>();
            var bruteForceSearcher = new BruteForceSearcher(reader);
            var pdfObjectParser    = new PdfObjectParser(container.Get <ILog>(), container.Get <CosBaseParser>(),
                                                         container.Get <CosStreamParser>(), crossReferenceTable, bruteForceSearcher, pool, container.Get <ObjectStreamParser>());

            var trueTypeFontParser    = new TrueTypeFontParser();
            var fontDescriptorFactory = new FontDescriptorFactory();

            var cidFontFactory = new CidFontFactory(fontDescriptorFactory, trueTypeFontParser, pdfObjectParser, filterProvider);

            var cMapCache = new CMapCache(new CMapParser());

            var fontFactory = new FontFactory(log, new Type0FontHandler(cidFontFactory,
                                                                        cMapCache,
                                                                        filterProvider,
                                                                        pdfObjectParser),
                                              new TrueTypeFontHandler(pdfObjectParser, filterProvider, cMapCache, fontDescriptorFactory, trueTypeFontParser));

            var dynamicParser     = container.Get <DynamicParser>();
            var resourceContainer = new ResourceContainer(pdfObjectParser, fontFactory);

            var pageFactory        = new PageFactory(resourceContainer, pdfObjectParser, filterProvider, new PageContentParser(new ReflectionGraphicsStateOperationFactory()));
            var informationFactory = new DocumentInformationFactory();
            var catalogFactory     = new CatalogFactory(pdfObjectParser);

            var root = ParseTrailer(reader, crossReferenceTable, dynamicParser, bruteForceSearcher, pool,
                                    isLenientParsing);

            if (!(root is PdfDictionary rootDictionary))
            {
                throw new InvalidOperationException("Expected root dictionary, but got this: " + root);
            }

            // in some pdfs the type value "Catalog" is missing in the root object
            if (isLenientParsing && !rootDictionary.ContainsKey(CosName.TYPE))
            {
                rootDictionary.Set(CosName.TYPE, CosName.CATALOG);
            }

            var information = informationFactory.Create(pdfObjectParser, crossReferenceTable.Dictionary, reader, isLenientParsing);

            var catalog = catalogFactory.Create(rootDictionary, reader, isLenientParsing);

            var caching = new ParsingCachingProviders(pool, bruteForceSearcher, resourceContainer);

            return(new PdfDocument(log, reader, version, crossReferenceTable, isLenientParsing, caching, pageFactory, pdfObjectParser, catalog, information));
        }
コード例 #18
0
        /// <summary>
        /// Check that the offsets in the cross reference are correct.
        /// </summary>
        public static bool ValidateCrossReferenceOffsets(IInputBytes bytes, CrossReferenceTable crossReferenceTable, ILog log,
                                                         out IReadOnlyDictionary <IndirectReference, long> actualOffsets)
        {
            actualOffsets = crossReferenceTable.ObjectOffsets;

            if (ValidateXrefOffsets(bytes, crossReferenceTable.ObjectOffsets, log))
            {
                return(true);
            }

            var builderOffsets = new Dictionary <IndirectReference, long>();

            var bruteForceOffsets = BruteForceSearcher.GetObjectLocations(bytes);

            if (bruteForceOffsets.Count > 0)
            {
                var objStreams = new List <IndirectReference>();

                // find all object streams
                foreach (var entry in crossReferenceTable.ObjectOffsets)
                {
                    var offset = entry.Value;
                    if (offset < 0)
                    {
                        var objStream = new IndirectReference(-offset, 0);
                        if (!objStreams.Contains(objStream))
                        {
                            objStreams.Add(new IndirectReference(-offset, 0));
                        }
                    }

                    // remove all found object streams
                    if (objStreams.Count > 0)
                    {
                        foreach (var key in objStreams)
                        {
                            if (bruteForceOffsets.ContainsKey(key))
                            {
                                // remove all parsed objects which are part of an object stream
                                //ISet<long> objects = xrefTrailerResolver
                                //    .getContainedObjectNumbers((int)(key.Number));
                                //foreach (long objNr in objects)
                                //{
                                //    CosObjectKey streamObjectKey = new CosObjectKey(objNr, 0);

                                //    if (bfCOSObjectKeyOffsets.TryGetValue(streamObjectKey, out long streamObjectOffset) && streamObjectOffset > 0)
                                //    {
                                //        bfCOSObjectKeyOffsets.Remove(streamObjectKey);
                                //    }
                                //}
                            }
                            else
                            {
                                // remove all objects which are part of an object stream which wasn't found
                                //ISet<long> objects = xrefTrailerResolver
                                //    .getContainedObjectNumbers((int)(key.Number));
                                //foreach (long objNr in objects)
                                //{
                                //    xrefOffset.Remove(new CosObjectKey(objNr, 0));
                                //}
                            }
                        }
                    }

                    foreach (var item in bruteForceOffsets)
                    {
                        builderOffsets[item.Key] = item.Value;
                    }
                }

                actualOffsets = builderOffsets;
            }

            return(false);
        }
コード例 #19
0
        public void ReaderNull_Throws()
        {
            Action action = () => BruteForceSearcher.GetObjectLocations(null);

            Assert.Throws <ArgumentNullException>(action);
        }
コード例 #20
0
ファイル: DynamicParser.cs プロジェクト: AnilAwadh/Pdf
        private CosBase ParseCompressedStreamObject(IRandomAccessRead reader, long streamObjectNumber, long requestedNumber, CosObjectPool objectPool, CrossReferenceTable crossReferenceTable, BruteForceSearcher bruteForceSearcher, bool isLenientParsing)
        {
            var baseStream = Parse(reader, streamObjectNumber, 0, objectPool, crossReferenceTable, bruteForceSearcher,
                                   isLenientParsing, true);

            if (!(baseStream is PdfRawStream stream))
            {
                log.Warn($"Could not find a stream for the object number, defaults to returning CosNull: {streamObjectNumber}");

                return(CosNull.Null);
            }

            var objects = objectStreamParser.Parse(stream, objectPool);

            // register all objects which are referenced to be contained in object stream
            foreach (var next in objects)
            {
                var streamKey = new CosObjectKey(next);
                var offset    = TryGet(streamKey, crossReferenceTable.ObjectOffsets);

                if (offset != null && offset == -streamObjectNumber)
                {
                    var streamObject = objectPool.Get(streamKey);
                    streamObject.SetObject(next.GetObject());
                }
            }

            var matchingStreamObject = objects.FirstOrDefault(x => x.GetObjectNumber() == requestedNumber);

            if (matchingStreamObject != null)
            {
                return(matchingStreamObject);
            }

            log.Error($"Could not find the object {requestedNumber} in the stream for object {streamObjectNumber}. Returning CosNull.");

            return(CosNull.Null);
        }
コード例 #21
0
 public ParsingCachingProviders(CosObjectPool objectPool, BruteForceSearcher bruteForceSearcher, IResourceStore resourceContainer)
 {
     ObjectPool         = objectPool ?? throw new ArgumentNullException(nameof(objectPool));
     BruteForceSearcher = bruteForceSearcher ?? throw new ArgumentNullException(nameof(bruteForceSearcher));
     ResourceContainer  = resourceContainer ?? throw new ArgumentNullException(nameof(resourceContainer));
 }
コード例 #22
0
        private static PdfDocument OpenDocument(IInputBytes inputBytes, ISeekableTokenScanner scanner, ILog log, bool isLenientParsing, IReadOnlyList <string> passwords)
        {
            var filterProvider = new MemoryFilterProvider(new DecodeParameterResolver(log), new PngPredictor(), log);

            CrossReferenceTable crossReferenceTable = null;

            var bruteForceSearcher = new BruteForceSearcher(inputBytes);
            var xrefValidator      = new XrefOffsetValidator(log);
            var objectChecker      = new XrefCosOffsetChecker(log, bruteForceSearcher);

            // We're ok with this since our intent is to lazily load the cross reference table.
            // ReSharper disable once AccessToModifiedClosure
            var locationProvider = new ObjectLocationProvider(() => crossReferenceTable, bruteForceSearcher);
            var pdfScanner       = new PdfTokenScanner(inputBytes, locationProvider, filterProvider, NoOpEncryptionHandler.Instance);

            var crossReferenceStreamParser = new CrossReferenceStreamParser(filterProvider);
            var crossReferenceParser       = new CrossReferenceParser(log, xrefValidator, objectChecker, crossReferenceStreamParser, new CrossReferenceTableParser());

            var version = FileHeaderParser.Parse(scanner, isLenientParsing, log);

            var crossReferenceOffset = FileTrailerParser.GetFirstCrossReferenceOffset(inputBytes, scanner,
                                                                                      isLenientParsing) + version.OffsetInFile;

            // TODO: make this use the scanner.
            var validator = new CrossReferenceOffsetValidator(xrefValidator);

            crossReferenceOffset = validator.Validate(crossReferenceOffset, scanner, inputBytes, isLenientParsing);

            crossReferenceTable = crossReferenceParser.Parse(inputBytes, isLenientParsing,
                                                             crossReferenceOffset,
                                                             version.OffsetInFile,
                                                             pdfScanner,
                                                             scanner);

            var fontDescriptorFactory = new FontDescriptorFactory();

            var(rootReference, rootDictionary) = ParseTrailer(crossReferenceTable, isLenientParsing,
                                                              pdfScanner,
                                                              out var encryptionDictionary);

            var encryptionHandler = encryptionDictionary != null ?
                                    (IEncryptionHandler) new EncryptionHandler(encryptionDictionary, crossReferenceTable.Trailer, passwords)
                : NoOpEncryptionHandler.Instance;

            pdfScanner.UpdateEncryptionHandler(encryptionHandler);

            var cidFontFactory = new CidFontFactory(pdfScanner, fontDescriptorFactory, filterProvider);
            var encodingReader = new EncodingReader(pdfScanner);

            var type1Handler = new Type1FontHandler(pdfScanner, filterProvider, fontDescriptorFactory, encodingReader);

            var fontFactory = new FontFactory(log, new Type0FontHandler(cidFontFactory,
                                                                        filterProvider, pdfScanner),
                                              new TrueTypeFontHandler(log, pdfScanner, filterProvider, fontDescriptorFactory, encodingReader, new SystemFontFinder(),
                                                                      type1Handler),
                                              type1Handler,
                                              new Type3FontHandler(pdfScanner, filterProvider, encodingReader));

            var resourceContainer = new ResourceStore(pdfScanner, fontFactory);

            var information = DocumentInformationFactory.Create(pdfScanner, crossReferenceTable.Trailer);

            var catalog = CatalogFactory.Create(rootReference, rootDictionary, pdfScanner, isLenientParsing);

            var pageFactory = new PageFactory(pdfScanner, resourceContainer, filterProvider,
                                              new PageContentParser(new ReflectionGraphicsStateOperationFactory()),
                                              log);

            var caching = new ParsingCachingProviders(bruteForceSearcher, resourceContainer);

            var acroFormFactory   = new AcroFormFactory(pdfScanner, filterProvider);
            var bookmarksProvider = new BookmarksProvider(log, pdfScanner, isLenientParsing);

            return(new PdfDocument(log, inputBytes, version, crossReferenceTable, isLenientParsing, caching, pageFactory, catalog, information,
                                   encryptionDictionary,
                                   pdfScanner,
                                   filterProvider,
                                   acroFormFactory,
                                   bookmarksProvider));
        }
コード例 #23
0
 public ParsingCachingProviders(BruteForceSearcher bruteForceSearcher, IResourceStore resourceContainer)
 {
     BruteForceSearcher = bruteForceSearcher ?? throw new ArgumentNullException(nameof(bruteForceSearcher));
     ResourceContainer  = resourceContainer ?? throw new ArgumentNullException(nameof(resourceContainer));
 }
コード例 #24
0
 public ObjectLocationProvider(Func <CrossReferenceTable> crossReferenceTable, BruteForceSearcher searcher)
 {
     this.crossReferenceTable = crossReferenceTable;
     this.searcher            = searcher;
 }
コード例 #25
0
        private static PdfDocument OpenDocument(IInputBytes inputBytes, ISeekableTokenScanner scanner, IContainer container, bool isLenientParsing, string password)
        {
            var log            = container.Get <ILog>();
            var filterProvider = container.Get <IFilterProvider>();
            var catalogFactory = new CatalogFactory();
            var cMapCache      = new CMapCache(new CMapParser());

            CrossReferenceTable crossReferenceTable = null;

            var bruteForceSearcher = new BruteForceSearcher(inputBytes);
            var xrefValidator      = new XrefOffsetValidator(log);
            var objectChecker      = new XrefCosOffsetChecker(log, bruteForceSearcher);

            // We're ok with this since our intent is to lazily load the cross reference table.
            // ReSharper disable once AccessToModifiedClosure
            var locationProvider = new ObjectLocationProvider(() => crossReferenceTable, bruteForceSearcher);
            var pdfScanner       = new PdfTokenScanner(inputBytes, locationProvider, filterProvider, NoOpEncryptionHandler.Instance);

            var crossReferenceStreamParser = new CrossReferenceStreamParser(filterProvider);
            var crossReferenceParser       = new CrossReferenceParser(log, xrefValidator, objectChecker, crossReferenceStreamParser, new CrossReferenceTableParser());

            var version = FileHeaderParser.Parse(scanner, isLenientParsing, log);

            var crossReferenceOffset = container.Get <FileTrailerParser>().GetFirstCrossReferenceOffset(inputBytes, scanner, isLenientParsing);

            // TODO: make this use the scanner.
            var validator = new CrossReferenceOffsetValidator(xrefValidator);

            crossReferenceOffset = validator.Validate(crossReferenceOffset, scanner, inputBytes, isLenientParsing);

            crossReferenceTable = crossReferenceParser.Parse(inputBytes, isLenientParsing, crossReferenceOffset, pdfScanner, scanner);

            var trueTypeFontParser           = new TrueTypeFontParser();
            var fontDescriptorFactory        = new FontDescriptorFactory();
            var compactFontFormatIndexReader = new CompactFontFormatIndexReader();
            var compactFontFormatParser      = new CompactFontFormatParser(new CompactFontFormatIndividualFontParser(compactFontFormatIndexReader, new CompactFontFormatTopLevelDictionaryReader(),
                                                                                                                     new CompactFontFormatPrivateDictionaryReader()), compactFontFormatIndexReader);

            var rootDictionary = ParseTrailer(crossReferenceTable, isLenientParsing, pdfScanner, out var encryptionDictionary);

            var encryptionHandler = encryptionDictionary != null ? (IEncryptionHandler) new EncryptionHandler(encryptionDictionary, crossReferenceTable.Trailer, password ?? string.Empty)
                : NoOpEncryptionHandler.Instance;

            pdfScanner.UpdateEncryptionHandler(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, 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, encodingReader));

            var resourceContainer = new ResourceContainer(pdfScanner, fontFactory);

            var pageFactory = new PageFactory(pdfScanner, resourceContainer, filterProvider,
                                              new PageContentParser(new ReflectionGraphicsStateOperationFactory()),
                                              new XObjectFactory(), log);
            var informationFactory = new DocumentInformationFactory();

            var information = informationFactory.Create(pdfScanner, crossReferenceTable.Trailer);

            var catalog = catalogFactory.Create(pdfScanner, rootDictionary);

            var caching = new ParsingCachingProviders(bruteForceSearcher, resourceContainer);

            var acroFormFactory = new AcroFormFactory(pdfScanner, filterProvider);

            return(new PdfDocument(log, inputBytes, version, crossReferenceTable, isLenientParsing, caching, pageFactory, catalog, information,
                                   encryptionDictionary,
                                   pdfScanner,
                                   filterProvider,
                                   acroFormFactory));
        }
コード例 #26
0
 public XrefCosOffsetChecker(ILog log, BruteForceSearcher bruteForceSearcher)
 {
     this.log = log;
     this.bruteForceSearcher = bruteForceSearcher;
 }