Hello PDFBox team,

we found a reproducible NullPointerException in PDFBox 3.0.6 while merging PDFs 
with output intents.

The issue occurs when the destination document already contains a 
PDOutputIntent without an OutputConditionIdentifier, and the source document 
contains a PDOutputIntent with a non-null identifier.

Expected behavior:

Merging should not throw a NullPointerException when an existing destination 
PDOutputIntent has no OutputConditionIdentifier. A missing identifier should 
simply not be treated as a duplicate match.
Below is a minimal JUnit 5 test that reproduces the issue.

import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
import org.junit.jupiter.api.Test;

class PDFMergerUtilityOutputIntentNpeTest {

    private byte[] createPdf(final String outputConditionIdentifier) throws 
Exception {

        final byte[] profileData = 
ICC_Profile.getInstance(ColorSpace.CS_sRGB).getData();

        try (final PDDocument doc = new PDDocument();
             final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            doc.addPage(new PDPage());
            final PDOutputIntent intent =
                    new PDOutputIntent(doc, new 
ByteArrayInputStream(profileData));
            if (outputConditionIdentifier != null) {
                intent.setOutputConditionIdentifier(outputConditionIdentifier);
            }
            doc.getDocumentCatalog().addOutputIntent(intent);
            doc.save(out);
            return out.toByteArray();
        }
    }

    @Test
    void 
reproducesNullPointerExceptionWhenDestinationOutputConditionIdentifierIsMissing()
            throws Exception {

        final byte[] destination = createPdf(null);
        final byte[] source = createPdf("sRGB IEC61966-2.1");
        final PDFMergerUtility merger = new PDFMergerUtility();
        merger.addSource(RandomAccessReadBuffer.createBufferFromStream(
                new ByteArrayInputStream(destination)));
        merger.addSource(RandomAccessReadBuffer.createBufferFromStream(
                new ByteArrayInputStream(source)));
        merger.setDestinationStream(new ByteArrayOutputStream());
        merger.mergeDocuments(IOUtils.createMemoryOnlyStreamCache());
    }

}

Since srcOCI is guaranteed to be non-null in this code path, reversing the 
equals comparison would avoid the NPE

Thanks

Julian

Reply via email to