예제 #1
0
        public void VersionFormatInvalidNotLenientThrows()
        {
            var scanner = StringBytesTestConverter.Scanner("%Pdeef-1.69");

            Action action = () => FileHeaderParser.Parse(scanner, false, log);

            Assert.Throws <PdfDocumentFormatException>(action);
        }
예제 #2
0
        public void JunkThenEndThrows()
        {
            var scanner = StringBytesTestConverter.Scanner(@"one two");

            Action action = () => FileHeaderParser.Parse(scanner, true, log);

            Assert.Throws <PdfDocumentFormatException>(action);
        }
예제 #3
0
        public void EmptyInputThrows()
        {
            var scanner = StringBytesTestConverter.Scanner(string.Empty);

            Action action = () => FileHeaderParser.Parse(scanner, false, log);

            Assert.Throws <PdfDocumentFormatException>(action);
        }
예제 #4
0
        public void ParsingResetsPosition()
        {
            var scanner = StringBytesTestConverter.Scanner(@"%FDF-1.6");

            FileHeaderParser.Parse(scanner, false, log);

            Assert.Equal(0, scanner.CurrentPosition);
        }
예제 #5
0
        public void VersionFormatInvalidLenientDefaults1Point4()
        {
            var scanner = StringBytesTestConverter.Scanner("%Pdeef-1.69");

            var result = FileHeaderParser.Parse(scanner, true, log);

            Assert.Equal(1.4m, result.Version);
        }
예제 #6
0
        public void ParsingResetsPosition()
        {
            var scanner = StringBytesTestConverter.Scanner(@"%FDF-1.6");

            var result = FileHeaderParser.Parse(scanner.scanner, scanner.bytes, false, log);

            Assert.Equal(0, scanner.scanner.CurrentPosition);
            Assert.Equal(0, result.OffsetInFile);
        }
예제 #7
0
        public void HeaderPrecededByJunkNonLenientThrows()
        {
            var scanner = StringBytesTestConverter.Scanner(@"one    
    %PDF-1.2");

            Action action = () => FileHeaderParser.Parse(scanner, false, log);

            Assert.Throws <PdfDocumentFormatException>(action);
        }
예제 #8
0
        public void HeaderPrecededByJunkLenientReads()
        {
            var scanner = StringBytesTestConverter.Scanner(@"one    
    %PDF-1.7");

            var result = FileHeaderParser.Parse(scanner, true, log);

            Assert.Equal(1.7m, result.Version);
        }
예제 #9
0
        public void HeaderPrecededByTooMuchJunkThrows()
        {
            var scanner = StringBytesTestConverter.Scanner(@"one two
three %PDF-1.6");

            Action action = () => FileHeaderParser.Parse(scanner, true, log);

            Assert.Throws <PdfDocumentFormatException>(action);
        }
예제 #10
0
        public void HeaderPrecededByJunkDoesNotThrow()
        {
            var scanner = StringBytesTestConverter.Scanner(@"one two
three %PDF-1.6");

            var result = FileHeaderParser.Parse(scanner, true, log);

            Assert.Equal(1.6m, result.Version);
            Assert.Equal(15, result.OffsetInFile);
        }
예제 #11
0
        public void HeaderPrecededByJunkNonLenientDoesNotThrow()
        {
            var scanner = StringBytesTestConverter.Scanner(@"one    
    %PDF-1.2");

            var result = FileHeaderParser.Parse(scanner, false, log);

            Assert.Equal(1.2m, result.Version);
            Assert.Equal(13, result.OffsetInFile);
        }
예제 #12
0
        public void HeaderPrecededByJunkLenientReads()
        {
            var scanner = StringBytesTestConverter.Scanner(@"one    
    %PDF-1.7");

            var result = FileHeaderParser.Parse(scanner.scanner, scanner.bytes, true, log);

            Assert.Equal(1.7m, result.Version);
            Assert.Equal(TestEnvironment.IsUnixPlatform ? 12 : 13, result.OffsetInFile);
        }
예제 #13
0
        public void Issue334()
        {
            var input = OtherEncodings.StringAsLatin1Bytes("%PDF-1.7\r\n%âãÏÓ\r\n1 0 obj\r\n<</Lang(en-US)>>\r\nendobj");

            var scanner = new CoreTokenScanner(new ByteArrayInputBytes(input), ScannerScope.None);

            var result = FileHeaderParser.Parse(scanner, false, log);

            Assert.Equal(1.7m, result.Version);
        }
예제 #14
0
        public void ReadsConformingHeader(string format)
        {
            var input = $"%{format}\nany garbage";

            var scanner = StringBytesTestConverter.Scanner(input);

            var result = FileHeaderParser.Parse(scanner, false, log);

            Assert.Equal(format, result.VersionString);
        }
예제 #15
0
        public void ReadsHeaderWithBlankSpaceBefore()
        {
            const string input = @"     

%PDF-1.2";

            var scanner = StringBytesTestConverter.Scanner(input);

            var result = FileHeaderParser.Parse(scanner, false, log);

            Assert.Equal(1.2m, result.Version);
        }
예제 #16
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());
        }
예제 #17
0
        public void ReadsHeaderWithBlankSpaceBefore()
        {
            const string input = @"     

%PDF-1.2";

            var scanner = StringBytesTestConverter.Scanner(input);

            var result = FileHeaderParser.Parse(scanner.scanner, scanner.bytes, false, log);

            Assert.Equal(1.2m, result.Version);
            Assert.Equal(TestEnvironment.IsUnixPlatform ? 7 : 9, result.OffsetInFile);
        }
예제 #18
0
        public void Issue443()
        {
            const string hex =
                @"00 0F 4A 43 42 31 33 36 36 31 32 32 37 2E 70 64 66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50 44 46 20 43 41 52 4F 01 00 FF FF FF FF 00 00 00 00 00 04 DF 28 00 00 00 00 AF 51 7E 82 AF 52 D7 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 81 81 03 0D 00 00 25 50 44 46 2D 31 2E 31 0A 25 E2 E3 CF D3 0D 0A 31 20 30 20 6F 62 6A";

            var bytes = hex.Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(x => HexToken.Convert(x[0], x[1]));

            var str = OtherEncodings.BytesAsLatin1String(bytes.ToArray());

            var scanner = StringBytesTestConverter.Scanner(str);

            var result = FileHeaderParser.Parse(scanner.scanner, scanner.bytes, false, log);

            Assert.Equal(0, scanner.scanner.CurrentPosition);
            Assert.Equal(128, result.OffsetInFile);
            Assert.Equal(1.1m, result.Version);
            Assert.Equal("PDF-1.1", result.VersionString);
        }
예제 #19
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));
        }
예제 #20
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));
        }
예제 #21
0
        public void NullScannerThrows()
        {
            Action action = () => FileHeaderParser.Parse(null, false, log);

            Assert.Throws <ArgumentNullException>(action);
        }