From ca954e8fc5832a7ff686e0b878951079d8f8fe12 Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Mon, 31 May 2021 18:20:57 +0200 Subject: possible fix of PDF-UA problem --- .../impl/signing/pdfbox2/PADESPDFBOXSigner.java | 63 +++++++++++++++++++--- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java index 6345a714..a33517cb 100644 --- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java +++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java @@ -64,6 +64,7 @@ import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDResources; +import org.apache.pdfbox.pdmodel.common.COSObjectable; import org.apache.pdfbox.pdmodel.common.PDMetadata; import org.apache.pdfbox.pdmodel.common.PDNumberTreeNode; import org.apache.pdfbox.pdmodel.common.PDRectangle; @@ -96,7 +97,10 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { @@ -213,7 +217,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } SignatureProfileSettings signatureProfileSettings = TableFactory .createProfile(requestedSignature.getSignatureProfileID(), pdfObject.getStatus().getSettings()); - //Check if input document is PDF-A conform + + //Check if input document is PDF-A conform if (signatureProfileSettings.isPDFA()) { DataSource origDoc = pdfObject.getOriginalDocument(); InputStream stream = origDoc.getInputStream(); @@ -510,12 +515,13 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } } - + PDStructureElement sigBlock = new PDStructureElement("Form", docElement); // create object dictionary and add as child element COSDictionary objectDic = new COSDictionary(); objectDic.setName("Type", "OBJR"); + objectDic.setItem("Pg", signatureField.getWidget().getPage()); objectDic.setItem("Obj", signatureField.getWidget()); @@ -541,7 +547,6 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { // Modify number tree PDNumberTreeNode ntn = structureTreeRoot.getParentTree(); - int parentTreeNextKey = structureTreeRoot.getParentTreeNextKey(); if (ntn == null) { ntn = new PDNumberTreeNode(objectDic, null); logger.info("No number-tree-node found!"); @@ -549,9 +554,10 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { COSArray ntnKids = (COSArray) ntn.getCOSObject().getDictionaryObject(COSName.KIDS); COSArray ntnNumbers = (COSArray) ntn.getCOSObject().getDictionaryObject(COSName.NUMS); - - if(ntnNumbers == null && ntnKids != null){//no number array, so continue with the kids array - + + int parentTreeNextKey = getParentTreeNextKey(structureTreeRoot); + + if(ntnNumbers == null && ntnKids != null){//no number array, so continue with the kids array //create dictionary with limits and nums array COSDictionary pTreeEntry = new COSDictionary(); COSArray limitsArray = new COSArray(); @@ -630,7 +636,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { byte[] outputDocument = bos.toByteArray(); pdfObject.setSignedDocument(outputDocument); } - /* Check if resulting pdf is PDF-A conform */ + /* Check if resulting pdf is PDF-A conform */ if (signatureProfileSettings.isPDFA()) { runPDFAPreflight(new ByteArrayDataSource(pdfObject.getSignedDocument())); } @@ -665,7 +671,23 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } } - /** + private int getParentTreeNextKey(PDStructureTreeRoot structureTreeRoot) throws IOException { + int nextKey = structureTreeRoot.getParentTreeNextKey(); + if (nextKey < 0) { + Map destNumberTreeAsMap = getNumberTreeAsMap(structureTreeRoot.getParentTree()); + if (destNumberTreeAsMap.isEmpty()) { + nextKey = 0; + + } else { + nextKey = Collections.max(destNumberTreeAsMap.keySet()) + 1; + + } + } + + return nextKey; + } + + /** * Check via PreFlightParser if PDF-Document is a valid PDFA1 * @param signedDocument: signed Document * @throws PdfAsException @@ -950,4 +972,29 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } return result; } + + static Map getNumberTreeAsMap(PDNumberTreeNode tree) + throws IOException + { + Map numbers = tree.getNumbers(); + if (numbers == null) + { + numbers = new LinkedHashMap<>(); + } + else + { + // must copy because the map is read only + numbers = new LinkedHashMap<>(numbers); + } + List kids = tree.getKids(); + if (kids != null) + { + for (PDNumberTreeNode kid : kids) + { + numbers.putAll(getNumberTreeAsMap(kid)); + } + } + return numbers; + } + } \ No newline at end of file -- cgit v1.2.3