Skip to content

Commit

Permalink
Signing ZUGFeRD document throws PdfAConformanceException
Browse files Browse the repository at this point in the history
(DEV-1650)
  • Loading branch information
Dmitry Trusevich committed Dec 23, 2015
1 parent 0383f85 commit d0da15f
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ public class PdfA1Checker extends PdfAChecker {
protected boolean cmykUsed = false;
protected boolean grayUsed = false;

protected String pdfaOutputIntentColorSpace = null;
protected PdfObject pdfaDestOutputIntent = null;

PdfA1Checker(PdfAConformanceLevel conformanceLevel) {
super(conformanceLevel);
}
Expand Down Expand Up @@ -302,6 +299,7 @@ protected void checkPdfObject(PdfWriter writer, int key, Object obj1) {
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("page.dictionary.shall.not.include.aa.entry"));
}
} else if (PdfName.OUTPUTINTENT.equals(type)) {
isCheckOutputIntent = true;
PdfObject destOutputIntent = dictionary.get(PdfName.DESTOUTPUTPROFILE);
if (destOutputIntent != null && pdfaDestOutputIntent != null) {
if (pdfaDestOutputIntent.getIndRef() != destOutputIntent.getIndRef())
Expand Down Expand Up @@ -518,6 +516,7 @@ protected void checkOutputIntent(PdfWriter writer, int key, Object obj1) {

@Override
public void close(PdfWriter writer) {
checkOutputIntentsInStamperMode(writer);
if ((rgbUsed || cmykUsed || grayUsed) && pdfaOutputIntentColorSpace == null) {
throw new PdfAConformanceException(null, MessageLocalization.getComposedMessage("if.device.rgb.cmyk.gray.used.in.file.that.file.shall.contain.pdfa.outputintent"));
}
Expand Down
38 changes: 19 additions & 19 deletions pdfa/src/main/java/com/itextpdf/text/pdf/internal/PdfA2Checker.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ PdfName.ALTERNATEPRESENTATION, PdfName.DOCMDP, PdfName.REFERENCE, new PdfName("D
protected boolean grayUsed = false;
protected boolean transparencyWithoutPageGroupDetected = false;
protected boolean transparencyDetectedOnThePage = false;
protected String pdfaOutputIntentColorSpace = null;
protected PdfObject pdfaDestOutputIntent = null;
static public final int maxStringLength = 32767;


Expand Down Expand Up @@ -135,7 +133,7 @@ protected void checkFont(PdfWriter writer, int key, Object obj1) {
@Override
protected void checkGState(PdfWriter writer, int key, Object obj1) {
if (obj1 instanceof PdfObject) {
PdfDictionary gs = getDirectDictionary((PdfObject)obj1);
PdfDictionary gs = getDirectDictionary((PdfObject) obj1);
PdfObject obj = gs.get(PdfName.BM);
if (obj != null) {
if (!allowedBlendModes.contains(obj))
Expand All @@ -144,7 +142,7 @@ protected void checkGState(PdfWriter writer, int key, Object obj1) {
transparencyDetectedOnThePage = true;
}

PdfNumber ca = gs.getAsNumber(PdfName.ca);
PdfNumber ca = gs.getAsNumber(PdfName.ca);
if (ca != null && ca.floatValue() < 1f) {
transparencyDetectedOnThePage = true;
}
Expand Down Expand Up @@ -194,7 +192,7 @@ protected void checkImage(PdfWriter writer, int key, Object obj1) {
if (getDirectStream(pdfImage.get(PdfName.SMASK)) != null) {
transparencyDetectedOnThePage = true;
}
PdfNumber smaskInData = pdfImage.getAsNumber(PdfName.SMASKINDATA) ;
PdfNumber smaskInData = pdfImage.getAsNumber(PdfName.SMASKINDATA);
if (smaskInData != null && smaskInData.floatValue() > 0) {
transparencyDetectedOnThePage = true;
}
Expand Down Expand Up @@ -251,7 +249,7 @@ protected void checkImage(PdfWriter writer, int key, Object obj1) {
@Override
protected void checkFormXObj(PdfWriter writer, int key, Object obj1) {
if (obj1 instanceof PdfTemplate) {
if (((PdfTemplate)obj1).getGroup() != null) {
if (((PdfTemplate) obj1).getGroup() != null) {
transparencyDetectedOnThePage = true;
}
}
Expand Down Expand Up @@ -405,7 +403,7 @@ protected void checkStream(PdfWriter writer, int key, Object obj1) {
@Override
protected void checkFileSpec(PdfWriter writer, int key, Object obj1) {
if (obj1 instanceof PdfFileSpecification) {
PdfDictionary fileSpec = (PdfFileSpecification)obj1;
PdfDictionary fileSpec = (PdfFileSpecification) obj1;
if (!fileSpec.contains(PdfName.UF) || !fileSpec.contains(PdfName.F) || !fileSpec.contains(PdfName.DESC)) {
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("file.specification.dictionary.shall.contain.f.uf.and.desc.entries"));
}
Expand Down Expand Up @@ -447,7 +445,7 @@ protected void checkPdfObject(PdfWriter writer, int key, Object obj1) {
if (string.getBytes().length > maxStringLength) {
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("pdf.string.is.too.long"));
}
} else if (obj1 instanceof PdfDictionary) {
} else if (obj1 instanceof PdfDictionary) {
PdfDictionary dictionary = (PdfDictionary) obj1;
PdfName type = dictionary.getAsName(PdfName.TYPE);
if (PdfName.CATALOG.equals(type)) {
Expand Down Expand Up @@ -493,14 +491,14 @@ protected void checkPdfObject(PdfWriter writer, int key, Object obj1) {
PdfDictionary referenceDict = getDirectDictionary(references.getPdfObject(i));
if (referenceDict.contains(DIGESTLOCATION)
|| referenceDict.contains(DIGESTMETHOD)
|| referenceDict.contains(DIGESTVALUE)) {
|| referenceDict.contains(DIGESTVALUE)) {
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("signature.references.dictionary.shall.not.contain.digestlocation.digestmethod.digestvalue"));
}
}
}
}
} else if (PdfName.UR3.equals(dictKey)){}
else {
} else if (PdfName.UR3.equals(dictKey)) {
} else {
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("no.keys.other.than.UR3.and.DocMDP.shall.be.present.in.a.permissions.dictionary"));
}
}
Expand All @@ -516,12 +514,12 @@ protected void checkPdfObject(PdfWriter writer, int key, Object obj1) {
}
}
} else if (PdfName.PAGE.equals(type)) {
PdfName[] boxNames = new PdfName[] {PdfName.MEDIABOX, PdfName.CROPBOX, PdfName.TRIMBOX, PdfName.ARTBOX, PdfName.BLEEDBOX};
for (PdfName boxName: boxNames) {
PdfName[] boxNames = new PdfName[]{PdfName.MEDIABOX, PdfName.CROPBOX, PdfName.TRIMBOX, PdfName.ARTBOX, PdfName.BLEEDBOX};
for (PdfName boxName : boxNames) {
PdfObject box = dictionary.getDirectObject(boxName);
if (box instanceof PdfRectangle) {
float width = ((PdfRectangle)box).width();
float height = ((PdfRectangle)box).height();
float width = ((PdfRectangle) box).width();
float height = ((PdfRectangle) box).height();
if (width < minPageSize || width > maxPageSize || height < minPageSize || height > maxPageSize)
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("the.page.less.3.units.nor.greater.14400.in.either.direction"));
}
Expand Down Expand Up @@ -551,6 +549,7 @@ protected void checkPdfObject(PdfWriter writer, int key, Object obj1) {
transparencyDetectedOnThePage = false;

} else if (PdfName.OUTPUTINTENT.equals(type)) {
isCheckOutputIntent = true;
PdfObject destOutputIntent = dictionary.get(PdfName.DESTOUTPUTPROFILE);
if (destOutputIntent != null && pdfaDestOutputIntent != null) {
if (pdfaDestOutputIntent.getIndRef() != destOutputIntent.getIndRef())
Expand Down Expand Up @@ -587,7 +586,7 @@ protected void checkPdfObject(PdfWriter writer, int key, Object obj1) {
}
PdfObject obj2 = dictionary.get(PdfName.HALFTONETYPE);
if (obj2 != null && obj2.isNumber()) {
PdfNumber number = (PdfNumber)obj2;
PdfNumber number = (PdfNumber) obj2;
if (number.intValue() != 1 || number.intValue() != 5) {
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("an.extgstate.dictionary.shall.contain.the.halftonetype.key.of.value.1.or.5"));
}
Expand Down Expand Up @@ -727,7 +726,7 @@ protected void checkAnnotation(PdfWriter writer, int key, Object obj1) {
PdfNumber index2 = rect.getAsNumber(2);
PdfNumber index3 = rect.getAsNumber(3);
if (index0 != null && index1 != null && index2 != null && index3 != null &&
index0.doubleValue() == index2.doubleValue() && index1.doubleValue() == index3.doubleValue())
index0.doubleValue() == index2.doubleValue() && index1.doubleValue() == index3.doubleValue())
isCorrectRect = true;
}
if (!PdfName.POPUP.equals(annot.getAsName(PdfName.SUBTYPE)) &&
Expand Down Expand Up @@ -787,8 +786,8 @@ protected void checkStructElem(PdfWriter writer, int key, Object obj1) {

@Override
protected void checkOutputIntent(PdfWriter writer, int key, Object obj1) {
if (writer instanceof PdfAStamperImp && writer.getColorProfile() != null)
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("outputintent.shall.not.be.updated"));
if (writer instanceof PdfAStamperImp && writer.getColorProfile() != null)
throw new PdfAConformanceException(obj1, MessageLocalization.getComposedMessage("outputintent.shall.not.be.updated"));
}

private void fillOrderRecursively(PdfArray orderArray, HashSet<PdfObject> order) {
Expand All @@ -804,6 +803,7 @@ private void fillOrderRecursively(PdfArray orderArray, HashSet<PdfObject> order)

@Override
public void close(PdfWriter writer) {
checkOutputIntentsInStamperMode(writer);
if (pdfaOutputIntentColorSpace != null) {
if ("RGB ".equals(pdfaOutputIntentColorSpace)) {
if (cmykUsed && writer.getDefaultColorspace().get(PdfName.DEFAULTCMYK) == null)
Expand Down
31 changes: 26 additions & 5 deletions pdfa/src/main/java/com/itextpdf/text/pdf/internal/PdfAChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
package com.itextpdf.text.pdf.internal;

import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.error_messages.MessageLocalization;
import com.itextpdf.text.io.TempFileCache;
import com.itextpdf.text.pdf.*;

Expand All @@ -63,6 +64,9 @@ abstract public class PdfAChecker {
TempFileCache fileCache;
private boolean isToUseExternalCache = false;
private HashMap<RefKey, TempFileCache.ObjectPosition> externallyCachedObjects = new HashMap<RefKey, TempFileCache.ObjectPosition>();
protected String pdfaOutputIntentColorSpace = null;
protected PdfObject pdfaDestOutputIntent = null;
protected boolean isCheckOutputIntent = false;

PdfAChecker(PdfAConformanceLevel conformanceLevel) {
this.conformanceLevel = conformanceLevel;
Expand All @@ -75,7 +79,7 @@ public void cacheObject(PdfIndirectReference iref, PdfObject obj) {
putObjectToCache(new RefKey(iref), obj);
} else if (obj instanceof PdfDictionary) {
putObjectToCache(new RefKey(iref), cleverPdfDictionaryClone((PdfDictionary) obj));
} else if (obj.isArray()){
} else if (obj.isArray()) {
putObjectToCache(new RefKey(iref), cleverPdfArrayClone((PdfArray) obj));
}
}
Expand All @@ -97,7 +101,7 @@ private PdfObject cleverPdfArrayClone(PdfArray array) {
for (int i = 0; i < array.size(); i++) {
PdfObject obj = array.getPdfObject(i);
if (obj instanceof PdfDictionary)
newArray.add(cleverPdfDictionaryClone((PdfDictionary)obj));
newArray.add(cleverPdfDictionaryClone((PdfDictionary) obj));
else
newArray.add(obj);
}
Expand Down Expand Up @@ -144,21 +148,21 @@ protected PdfObject getDirectObject(PdfObject obj) {
protected PdfDictionary getDirectDictionary(PdfObject obj) {
obj = getDirectObject(obj);
if (obj != null && obj instanceof PdfDictionary)
return (PdfDictionary)obj;
return (PdfDictionary) obj;
return null;
}

protected PdfStream getDirectStream(PdfObject obj) {
obj = getDirectObject(obj);
if (obj != null && obj.isStream())
return (PdfStream)obj;
return (PdfStream) obj;
return null;
}

protected PdfArray getDirectArray(PdfObject obj) {
obj = getDirectObject(obj);
if (obj != null && obj.isArray())
return (PdfArray)obj;
return (PdfArray) obj;
return null;
}

Expand Down Expand Up @@ -301,4 +305,21 @@ private PdfObject getObjectFromCache(RefKey ref) {
return cachedObjects.get(ref);
}
}

protected void checkOutputIntentsInStamperMode(PdfWriter writer) {
if (writer instanceof PdfAStamperImp && !isCheckOutputIntent) {
PdfReader pdfReader = ((PdfAStamperImp) writer).getPdfReader();
PdfArray outPutIntentsDic = pdfReader.getCatalog().getAsArray(PdfName.OUTPUTINTENTS);
if (outPutIntentsDic != null) {
if (outPutIntentsDic.size() > 1) {
throw new PdfAConformanceException(outPutIntentsDic, MessageLocalization.getComposedMessage("a.pdfa.file.may.have.only.one.pdfa.outputintent"));
} else {
PdfDictionary outPutIntentDic = outPutIntentsDic.getAsDict(0);
if (outPutIntentDic != null) {
checkPdfObject(writer, PdfIsoKeys.PDFISOKEY_OBJECT, outPutIntentDic);
}
}
}
}
}
}

0 comments on commit d0da15f

Please sign in to comment.