简体   繁体   中英

Issue merging PDFs on iText7

I have the below method that merges my PDF documents. However, in some cases where the document has a watermark, the method throws me an error.

public void doMergeUsingItext7(List<InputStream> list, OutputStream outputStream) throws SSException {
    try (com.itextpdf.kernel.pdf.PdfWriter writer = new com.itextpdf.kernel.pdf.PdfWriter(outputStream);) {
        writer.setSmartMode(Boolean.TRUE);
        try (com.itextpdf.kernel.pdf.PdfDocument pdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(writer)) {
            pdfDoc.initializeOutlines();
            list.forEach((in) -> {
                try (com.itextpdf.kernel.pdf.PdfReader reader = new com.itextpdf.kernel.pdf.PdfReader(in);) {
                    reader.setUnethicalReading(Boolean.TRUE);
                    try (com.itextpdf.kernel.pdf.PdfDocument addedDoc = new com.itextpdf.kernel.pdf.PdfDocument(reader)) { //ERROR IS THROWN ON THIS LINE
                        addedDoc.copyPagesTo(1, addedDoc.getNumberOfPages(), pdfDoc);
                        logger.log(Level.INFO, "Successfully Added the Document to PDF");
                    } catch (Exception e) {
                        ExceptionUtils.printRootCauseStackTrace(e);
                    }
                } catch (IOException ex) {
                    ExceptionUtils.printRootCauseStackTrace(ex);
                } catch (Exception e) {
                    ExceptionUtils.printRootCauseStackTrace(e);
                }
            });
        }
    } catch (Exception ex) {
        throw new SSException(ex, "Print Version Failed");
    }
}

The following error is thrown when the document has a watermark...

com.itextpdf.kernel.PdfException: Illegal length value.
at com.itextpdf.kernel.pdf.PdfEncryption.readAndSetCryptoModeForStdHandler(PdfEncryption.java:523)
at com.itextpdf.kernel.pdf.PdfEncryption.<init>(PdfEncryption.java:229)
at com.itextpdf.kernel.pdf.PdfReader.readDecryptObj(PdfReader.java:1251)
at com.itextpdf.kernel.pdf.PdfReader.readPdf(PdfReader.java:685)
at com.itextpdf.kernel.pdf.PdfDocument.open(PdfDocument.java:1871)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:252)
at com.itextpdf.kernel.pdf.PdfDocument.<init>(PdfDocument.java:234)
at gov.ca.lc.util.PdfUtilFuntions.lambda$doMergeUsingItext7$0(PdfUtilFuntions.java:180)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at gov.ca.lc.util.PdfUtilFuntions.doMergeUsingItext7(PdfUtilFuntions.java:176)

I am not sure what exactly within the document is failing to merge. Any help on fixing this issue is highly appreciated. Thanks.

This is a bug in iText.

The PDF in question is encrypted. Its encryption dictionary has a V value of 1 ("RC4 or AES algorithms with an encryption key length of 40 bits") and an R value of 3 ("for files encrypted with a V value of 2 or 3, or with any “Security handlers of revision 3 or greater” access permissions set to 0").

A Length value for the key length is specified only for V 2 or 3, for V 1 the key length is fixed to 40. Nonetheless, iText in case of R 3 requires a Length value.

As there is no Length value in the encryption dictionary of your document, iText fails reading that file.


As a side note: 40 bit key length security nowadays is no security. So most likely that issue did not pop up earlier because using V 1 security (or 40 bit key length security in general) is useless and, therefore, no use case taken seriously.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM