Exemple #1
0
        public static IContainer GenerateContainer(ILog logger)
        {
            if (_testContainer != null)
            {
                return(_testContainer);
            }

            if (logger == null)
            {
                logger = new NoOpLog();
            }

            var headerParser   = new FileHeaderParser(logger);
            var trailerParser  = new FileTrailerParser();
            var filterProvider = new MemoryFilterProvider(new DecodeParameterResolver(logger), new PngPredictor(), logger);

            var cmapParser = new CMapParser();
            var afmParser  = new AdobeFontMetricsParser();

            var container = new Container();

            container.Register(headerParser);
            container.Register(trailerParser);
            container.Register(filterProvider);
            container.Register(cmapParser);
            container.Register(afmParser);
            container.Register(logger);

            return(container);
        }
Exemple #2
0
        public void NullScannerThrows()
        {
            var input = StringBytesTestConverter.Convert("11 0 obj", false);

            Action action = () => FileTrailerParser.GetFirstCrossReferenceOffset(input.Bytes, null, false);

            Assert.Throws <ArgumentNullException>(action);
        }
Exemple #3
0
        public void CanReadStartXrefIfCommentsPresent()
        {
            var input = StringBytesTestConverter.Convert(@"
startxref %Commented here
    57695

%%EOF", false);

            var result = FileTrailerParser.GetFirstCrossReferenceOffset(input.Bytes, new CoreTokenScanner(input.Bytes), false);

            Assert.Equal(57695, result);
        }
Exemple #4
0
        /// <summary>
        /// Merge the set of PDF documents.
        /// </summary>
        public static byte[] Merge(IReadOnlyList <byte[]> files, IReadOnlyList <IReadOnlyList <int> > pagesBundle = null)
        {
            if (files == null)
            {
                throw new ArgumentNullException(nameof(files));
            }

            const bool isLenientParsing = false;

            var documentBuilder = new DocumentMerger();

            foreach (var fileIndex in Enumerable.Range(0, files.Count))
            {
                var file = files[fileIndex];

                IReadOnlyList <int> pages = null;
                if (pagesBundle != null && fileIndex < pagesBundle.Count)
                {
                    pages = pagesBundle[fileIndex];
                }

                var inputBytes  = new ByteArrayInputBytes(file);
                var coreScanner = new CoreTokenScanner(inputBytes);

                var version = FileHeaderParser.Parse(coreScanner, isLenientParsing, Log);

                var crossReferenceParser = new CrossReferenceParser(Log, new XrefOffsetValidator(Log),
                                                                    new Parser.Parts.CrossReference.CrossReferenceStreamParser(FilterProvider));

                CrossReferenceTable crossReference = null;

                // ReSharper disable once AccessToModifiedClosure
                var locationProvider = new ObjectLocationProvider(() => crossReference, inputBytes);

                var pdfScanner = new PdfTokenScanner(inputBytes, locationProvider, FilterProvider, NoOpEncryptionHandler.Instance);

                var crossReferenceOffset = FileTrailerParser.GetFirstCrossReferenceOffset(inputBytes, coreScanner, isLenientParsing);
                crossReference = crossReferenceParser.Parse(inputBytes, isLenientParsing, crossReferenceOffset, version.OffsetInFile, pdfScanner, coreScanner);

                var catalogDictionaryToken = ParseCatalog(crossReference, pdfScanner, out var encryptionDictionary);
                if (encryptionDictionary != null)
                {
                    throw new PdfDocumentEncryptedException("Unable to merge document with password");
                }

                var documentCatalog = CatalogFactory.Create(crossReference.Trailer.Root, catalogDictionaryToken, pdfScanner, isLenientParsing);

                documentBuilder.AppendDocument(documentCatalog, version.Version, pdfScanner, pages);
            }

            return(documentBuilder.Build());
        }
Exemple #5
0
        public void MissingNumericAfterStartXrefThrows()
        {
            var input = StringBytesTestConverter.Convert(@"11 0 obj
        << /Type/Font >>
endobj

startxref 
   ", false);

            Action action = () => FileTrailerParser.GetFirstCrossReferenceOffset(input.Bytes, new CoreTokenScanner(input.Bytes), false);

            Assert.Throws <PdfDocumentFormatException>(action);
        }
Exemple #6
0
        public static IContainer GenerateContainer(ILog logger)
        {
            if (_testContainer != null)
            {
                return(_testContainer);
            }

            if (logger == null)
            {
                logger = new NoOpLog();
            }

            var headerParser         = new FileHeaderParser(logger);
            var trailerParser        = new FileTrailerParser();
            var nameParser           = new CosNameParser();
            var dictionaryParser     = new CosDictionaryParser(nameParser, logger);
            var baseParser           = new CosBaseParser(nameParser, new CosStringParser(), dictionaryParser, new CosArrayParser());
            var streamParser         = new CosStreamParser(logger);
            var filterProvider       = new MemoryFilterProvider(new DecodeParameterResolver(logger), new PngPredictor(), logger);
            var crossReferenceParser = new CrossReferenceStreamParser(filterProvider);
            var objectStreamParser   = new ObjectStreamParser(logger, filterProvider, baseParser);
            var dynamicParser        = new DynamicParser(logger, baseParser, streamParser, objectStreamParser);

            var crossReferenceTableParser = new CrossReferenceParser(logger, dictionaryParser, baseParser, streamParser, crossReferenceParser, new CrossReferenceTableParser(),
                                                                     new OldCrossReferenceTableParser(logger, dictionaryParser, baseParser));

            var cmapParser = new CMapParser();
            var afmParser  = new AdobeFontMetricsParser();

            var container = new Container();

            container.Register(headerParser);
            container.Register(trailerParser);
            container.Register(nameParser);
            container.Register(dictionaryParser);
            container.Register(baseParser);
            container.Register(streamParser);
            container.Register(crossReferenceParser);
            container.Register(crossReferenceTableParser);
            container.Register(dynamicParser);
            container.Register(objectStreamParser);
            container.Register(filterProvider);
            container.Register(cmapParser);
            container.Register(afmParser);
            container.Register(logger);

            return(container);
        }
Exemple #7
0
        public void FindsCompliantStartXref()
        {
            var input = StringBytesTestConverter.Convert(@"sta455%r endstream
endobj

12 0 obj
1234  %eof
endobj

startxref
    456

%%EOF", false);

            var result = FileTrailerParser.GetFirstCrossReferenceOffset(input.Bytes, new CoreTokenScanner(input.Bytes), false);

            Assert.Equal(456, result);
        }
Exemple #8
0
        public void MissingStartXrefThrows()
        {
            var input = StringBytesTestConverter.Convert(@"11 0 obj
<< /Type/Something /W[12 0 5 6] >>
endobj

12 0 obj
1234  %eof
endobj

startref
    1384733

%%EOF

% I decided to put some nonsense here:
% because I could hahaha
start_rexf
17", false);

            Action action = () => FileTrailerParser.GetFirstCrossReferenceOffset(input.Bytes, new CoreTokenScanner(input.Bytes), false);

            Assert.Throws <PdfDocumentFormatException>(action);
        }
Exemple #9
0
        public void IncludesStartXrefFollowingEndOfFile()
        {
            var input = StringBytesTestConverter.Convert(@"11 0 obj
<< /Type/Something /W[12 0 5 6] >>
endobj

12 0 obj
1234  %eof
endobj

startxref
    1384733

%%EOF

% I decided to put some nonsense here:
% because I could hahaha
startxref
17", false);

            var result = FileTrailerParser.GetFirstCrossReferenceOffset(input.Bytes, new CoreTokenScanner(input.Bytes), false);

            Assert.Equal(17, result);
        }
Exemple #10
0
        public void TakesLastStartXrefPrecedingEndOfFile()
        {
            var input = StringBytesTestConverter.Convert(@"11 0 obj
<< /Type/Something /W[12 0 5 6] >>
endobj

12 0 obj
1234  %eof
endobj

startxref
    1384733

%actually I changed my mind

startxref
         1274665676543

%%EOF", false);

            var result = FileTrailerParser.GetFirstCrossReferenceOffset(input.Bytes, new CoreTokenScanner(input.Bytes), false);

            Assert.Equal(1274665676543, result);
        }
Exemple #11
0
        private static PdfDocument OpenDocument(IInputBytes inputBytes, ISeekableTokenScanner scanner, ILog log, bool isLenientParsing,
                                                IReadOnlyList <string> passwords, bool clipPaths)
        {
            var filterProvider = DefaultFilterProvider.Instance;

            CrossReferenceTable crossReferenceTable = null;

            var xrefValidator = new XrefOffsetValidator(log);

            // 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, inputBytes);
            var pdfScanner       = new PdfTokenScanner(inputBytes, locationProvider, filterProvider, NoOpEncryptionHandler.Instance);

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

            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(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, filterProvider);
            var encodingReader = new EncodingReader(pdfScanner);

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

            var fontFactory = new FontFactory(log, new Type0FontHandler(cidFontFactory,
                                                                        filterProvider, pdfScanner),
                                              new TrueTypeFontHandler(log, pdfScanner, filterProvider, encodingReader, SystemFontFinder.Instance,
                                                                      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(resourceContainer);

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

            return(new PdfDocument(log, inputBytes, version, crossReferenceTable, caching, pageFactory, catalog, information,
                                   encryptionDictionary,
                                   pdfScanner,
                                   filterProvider,
                                   acroFormFactory,
                                   bookmarksProvider,
                                   clipPaths));
        }