You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/07/04 21:39:09 UTC
svn commit: r1607917 -
/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/process/reflect/ResourcesValidationProcess.java
Author: jahewson
Date: Fri Jul 4 19:39:09 2014
New Revision: 1607917
URL: http://svn.apache.org/r1607917
Log:
PDFBOX-2179: Preflight: handle damaged font IOExceptions from PDFont in a format-specific manner
Modified:
pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/process/reflect/ResourcesValidationProcess.java
Modified: pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/process/reflect/ResourcesValidationProcess.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/process/reflect/ResourcesValidationProcess.java?rev=1607917&r1=1607916&r2=1607917&view=diff
==============================================================================
--- pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/process/reflect/ResourcesValidationProcess.java (original)
+++ pdfbox/trunk/preflight/src/main/java/org/apache/pdfbox/preflight/process/reflect/ResourcesValidationProcess.java Fri Jul 4 19:39:09 2014
@@ -27,11 +27,13 @@ import static org.apache.pdfbox.prefligh
import static org.apache.pdfbox.preflight.PreflightConfiguration.SHADDING_PATTERN_PROCESS;
import static org.apache.pdfbox.preflight.PreflightConfiguration.TILING_PATTERN_PROCESS;
import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_DICTIONARY_INVALID;
+import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_FONTS_TRUETYPE_DAMAGED;
import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_GRAPHIC_INVALID_PATTERN_DEFINITION;
import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_PDF_PROCESSING_MISSING;
import static org.apache.pdfbox.preflight.PreflightConstants.TRANPARENCY_DICTIONARY_KEY_EXTGSTATE;
import java.io.IOException;
+import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -42,6 +44,12 @@ import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDFontFactory;
+import org.apache.pdfbox.pdmodel.font.PDMMType1Font;
+import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.apache.pdfbox.pdmodel.font.PDType3Font;
import org.apache.pdfbox.pdmodel.graphics.pattern.PDAbstractPattern;
import org.apache.pdfbox.pdmodel.graphics.pattern.PDTilingPattern;
import org.apache.pdfbox.pdmodel.graphics.shading.PDShading;
@@ -90,20 +98,114 @@ public class ResourcesValidationProcess
*/
protected void validateFonts(PreflightContext context, PDResources resources) throws ValidationException
{
- try
+ Map<String, PDFont> mapOfFonts = getFonts(resources.getCOSDictionary(), context);
+ if (mapOfFonts != null)
+ {
+ for (Entry<String, PDFont> entry : mapOfFonts.entrySet())
+ {
+ ContextHelper.validateElement(context, entry.getValue(), FONT_PROCESS);
+ }
+ }
+ }
+
+ /**
+ * This will get the map of fonts. This will never return null.
+ *
+ * @return The map of fonts.
+ */
+ private Map<String, PDFont> getFonts(COSDictionary resources, PreflightContext context)
+ {
+ Map<String, PDFont> fonts = new HashMap<String, PDFont>();
+ COSDictionary fontsDictionary = (COSDictionary) resources.getDictionaryObject(COSName.FONT);
+ if (fontsDictionary == null)
+ {
+ fontsDictionary = new COSDictionary();
+ resources.setItem(COSName.FONT, fontsDictionary);
+ }
+ for (COSName fontName : fontsDictionary.keySet())
{
- Map<String, PDFont> mapOfFonts = resources.getFonts();
- if (mapOfFonts != null)
+ COSBase font = fontsDictionary.getDictionaryObject(fontName);
+ // data-000174.pdf contains a font that is a COSArray, looks to be an error in the
+ // PDF, we will just ignore entries that are not dictionaries.
+ if (font instanceof COSDictionary)
{
- for (Entry<String, PDFont> entry : mapOfFonts.entrySet())
+ PDFont newFont = null;
+ try
+ {
+ newFont = PDFontFactory.createFont((COSDictionary) font);
+ }
+ catch (IOException e)
{
- ContextHelper.validateElement(context, entry.getValue(), FONT_PROCESS);
+ addFontError((COSDictionary)font, context);
+ }
+ if (newFont != null)
+ {
+ fonts.put(fontName.getName(), newFont);
}
}
}
- catch (IOException e)
+ return fonts;
+ }
+
+ /**
+ * PDFont loads embedded fonts in its constructor so we have to handle IOExceptions
+ * from PDFont and translate them into validation errors.
+ */
+ private void addFontError(COSDictionary dictionary, PreflightContext context)
+ {
+ COSName type = dictionary.getCOSName(COSName.TYPE, COSName.FONT);
+ if (!COSName.FONT.equals(type))
+ {
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_UNKNOWN_FONT_TYPE,
+ "Expected 'Font' dictionary but found '" + type.getName() + "'"));
+ }
+
+ String fontName = "Unknown";
+ if (dictionary.containsKey(COSName.BASE_FONT))
+ {
+ fontName = dictionary.getNameAsString(COSName.BASE_FONT);
+ }
+
+ COSName subType = dictionary.getCOSName(COSName.SUBTYPE);
+ if (COSName.TYPE1.equals(subType))
+ {
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_TYPE1_DAMAGED,
+ "The FontFile can't be read for " + fontName));
+ }
+ else if (COSName.MM_TYPE1.equals(subType))
+ {
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_TYPE1_DAMAGED,
+ "The FontFile can't be read for " + fontName));
+ }
+ else if (COSName.TRUE_TYPE.equals(subType))
+ {
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_TRUETYPE_DAMAGED,
+ "The FontFile can't be read for " + fontName));
+ }
+ else if (COSName.TYPE3.equals(subType))
+ {
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_TYPE3_DAMAGED,
+ "The FontFile can't be read for " + fontName));
+ }
+ else if (COSName.TYPE0.equals(subType))
+ {
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_CID_DAMAGED,
+ "The FontFile can't be read for " + fontName));
+ }
+ else if (COSName.CID_FONT_TYPE0.equals(subType))
+ {
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_UNKNOWN_FONT_TYPE,
+ "Unexpected CIDFontType0 descendant font for " + fontName));
+ }
+ else if (COSName.CID_FONT_TYPE2.equals(subType))
+ {
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_UNKNOWN_FONT_TYPE,
+ "Unexpected CIDFontType2 descendant font for " + fontName));
+ }
+ else
{
- context.addValidationError(new ValidationError(ERROR_FONTS_DICTIONARY_INVALID, "Could not read font"));
+ addValidationError(context, new ValidationError(PreflightConstants.ERROR_FONTS_UNKNOWN_FONT_TYPE,
+ "Unknown font type for " + fontName));
}
}