use of org.apache.pdfbox.cos.COSObjectKey in project pdfbox by apache.
the class ActionManagerFactory method callCreateAction.
/**
* Call the create action to add the ActionManager to the result list. If the aDict parameter isn't an instance of
* COSDictionary, this method throws a ValdiationException. If the aDict parameter is a reference to a
* COSDicitonary, the action manager is create only if the linked COSObjectKey is missing from the "alreadyCreated"
* map, in this case the action is added to the map. If the aDict parameter is an instance of COSDIctionary, it is
* impossible to check if the ActionManager already exists in the "alreadyCreated" map.
*
* @param aDict
* a COSBase object (COSObject or COSDictionary) which represent the action dictionary.
* @param ctx
* the preflight validation context.
* @param result
* the list of ActionManager to updated if the aDict parameter is valid.
* @param additionActionKey
* the Action identifier if it is an additional action
* @param alreadyCreated
* This map is used to know if an Action has already been validated. It is useful to avoid infinite loop
* in an action which has a Next entry.
* @throws ValidationException
*/
private void callCreateAction(COSBase aDict, PreflightContext ctx, List<AbstractActionManager> result, String additionActionKey, Map<COSObjectKey, Boolean> alreadyCreated) throws ValidationException {
COSDocument cosDocument = ctx.getDocument().getDocument();
if (COSUtils.isDictionary(aDict, cosDocument)) {
if (aDict instanceof COSObject) {
COSObjectKey cok = new COSObjectKey((COSObject) aDict);
if (!alreadyCreated.containsKey(cok)) {
result.add(createActionManager(ctx, COSUtils.getAsDictionary(aDict, cosDocument), additionActionKey));
alreadyCreated.put(cok, true);
}
} else {
result.add(createActionManager(ctx, COSUtils.getAsDictionary(aDict, cosDocument), additionActionKey));
}
} else {
ctx.addValidationError(new ValidationError(PreflightConstants.ERROR_ACTION_INVALID_TYPE, "Action entry isn't an instance of COSDictionary"));
}
}
use of org.apache.pdfbox.cos.COSObjectKey in project pdfbox by apache.
the class PreflightParser method parseXrefTable.
/**
* Same method than the {@linkplain PDFParser#parseXrefTable(long)} with additional controls : -
* EOL mandatory after the 'xref' keyword - Cross reference subsection header uses single white
* space as separator - and so on
*
* @param startByteOffset the offset to start at
* @return false on parsing error
* @throws IOException If an IO error occurs.
*/
@Override
protected boolean parseXrefTable(long startByteOffset) throws IOException {
if (source.peek() != 'x') {
return false;
}
String xref = readString();
if (!xref.equals("xref")) {
addValidationError(new ValidationError(PreflightConstants.ERROR_SYNTAX_CROSS_REF, "xref must be followed by a EOL character"));
return false;
}
if (!nextIsEOL()) {
addValidationError(new ValidationError(PreflightConstants.ERROR_SYNTAX_CROSS_REF, "xref must be followed by EOL"));
}
// signal start of new XRef
xrefTrailerResolver.nextXrefObj(startByteOffset, XRefType.TABLE);
// Xref tables can have multiple sections. Each starts with a starting object id and a count.
while (true) {
// just after the xref<EOL> there are an integer
// first obj id
long currObjID;
// the number of objects in the xref table
int count;
long offset = source.getPosition();
String line = readLine();
Pattern pattern = Pattern.compile("(\\d+)\\s(\\d+)(\\s*)");
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
currObjID = Long.parseLong(matcher.group(1));
count = Integer.parseInt(matcher.group(2));
} else {
addValidationError(new ValidationError(ERROR_SYNTAX_CROSS_REF, "Cross reference subsection header is invalid: '" + line + "' at position " + source.getPosition()));
// reset source cursor to read xref information
source.seek(offset);
// first obj id
currObjID = readObjectNumber();
// the number of objects in the xref table
count = readInt();
}
skipSpaces();
for (int i = 0; i < count; i++) {
if (source.isEOF() || isEndOfName((char) source.peek())) {
break;
}
if (source.peek() == 't') {
addValidationError(new ValidationError(PreflightConstants.ERROR_SYNTAX_CROSS_REF, "Expected xref line but 't' found"));
break;
}
// Ignore table contents
String currentLine = readLine();
String[] splitString = currentLine.split(" ");
if (splitString.length < 3) {
addValidationError(new ValidationError(PreflightConstants.ERROR_SYNTAX_CROSS_REF, "invalid xref line: " + currentLine));
break;
}
// This supports the corrupt table as reported in PDFBOX-474 (XXXX XXX XX n)
if (splitString[splitString.length - 1].equals("n")) {
try {
long currOffset = Long.parseLong(splitString[0]);
int currGenID = Integer.parseInt(splitString[1]);
COSObjectKey objKey = new COSObjectKey(currObjID, currGenID);
xrefTrailerResolver.setXRef(objKey, currOffset);
} catch (NumberFormatException e) {
addValidationError(new ValidationError(PreflightConstants.ERROR_SYNTAX_CROSS_REF, "offset or genid can't be read as number " + e.getMessage(), e));
}
} else if (!splitString[2].equals("f")) {
addValidationError(new ValidationError(PreflightConstants.ERROR_SYNTAX_CROSS_REF, "Corrupt XRefTable Entry - ObjID:" + currObjID));
}
currObjID++;
skipSpaces();
}
skipSpaces();
if (!isDigit()) {
break;
}
}
return true;
}
use of org.apache.pdfbox.cos.COSObjectKey in project pdfbox by apache.
the class CatalogValidationProcess method validateICCProfile.
/**
* This method checks the destOutputProfile which must be a valid ICCProfile.
*
* If an other ICCProfile exists in the mapDestOutputProfile, a ValdiationError
* (ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_MULTIPLE) is returned because of only one profile is authorized. If the
* ICCProfile already exist in the mapDestOutputProfile, the method returns null. If the destOutputProfile contains
* an invalid ICCProfile, a ValidationError (ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_INVALID) is returned If the
* destOutputProfile is an empty stream, a ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY) is returned.
*
* If the destOutputFile is valid, mapDestOutputProfile is updated, the ICCProfile is added to the document ctx and
* null is returned.
*
* @param destOutputProfile
* @param mapDestOutputProfile
* @param ctx the preflight context.
* @throws ValidationException
*/
protected void validateICCProfile(COSBase destOutputProfile, Map<COSObjectKey, Boolean> mapDestOutputProfile, PreflightContext ctx) throws ValidationException {
try {
if (destOutputProfile == null) {
return;
}
// destOutputProfile should be an instance of COSObject because of this is a object reference
if (destOutputProfile instanceof COSObject) {
if (mapDestOutputProfile.containsKey(new COSObjectKey((COSObject) destOutputProfile))) {
// the profile is already checked. continue
return;
} else if (!mapDestOutputProfile.isEmpty()) {
// A DestOutputProfile exits but it isn't the same, error
addValidationError(ctx, new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_MULTIPLE, "More than one ICCProfile is defined"));
return;
}
// else the profile will be kept in the tmpDestOutputProfile if it is valid
}
// keep reference to avoid multiple profile definition
mapDestOutputProfile.put(new COSObjectKey((COSObject) destOutputProfile), true);
COSDocument cosDocument = ctx.getDocument().getDocument();
COSStream stream = COSUtils.getAsStream(destOutputProfile, cosDocument);
if (stream == null) {
addValidationError(ctx, new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_INVALID_ENTRY, "OutputIntent object uses a NULL Object"));
return;
}
InputStream is = stream.createInputStream();
ICC_Profile iccp = null;
try {
iccp = ICC_Profile.getInstance(is);
} finally {
is.close();
}
if (!validateICCProfileNEntry(stream, ctx, iccp)) {
return;
}
if (!validateICCProfileVersion(iccp, ctx)) {
return;
}
if (ctx.getIccProfileWrapper() == null) {
ctx.setIccProfileWrapper(new ICCProfileWrapper(iccp));
}
} catch (IllegalArgumentException e) {
// this is not a ICC_Profile
addValidationError(ctx, new ValidationError(ERROR_GRAPHIC_OUTPUT_INTENT_ICC_PROFILE_INVALID, "DestOutputProfile isn't a valid ICCProfile: " + e.getMessage(), e));
} catch (IOException e) {
throw new ValidationException("Unable to parse the ICC Profile.", e);
}
}
use of org.apache.pdfbox.cos.COSObjectKey in project pdfbox by apache.
the class COSUtils method getAsFloat.
/**
* Return the COSBase object as Float if the COSBase object is an instance of COSFloat or a reference to a COSFloat
* object. In other cases, this method returns null;
*
* @param cbase the object to get.
* @param cDoc the document.
* @return the object as Float if the object is a COSFloat or a reference to it. Returns null otherwise.
*/
public static Float getAsFloat(COSBase cbase, COSDocument cDoc) {
if (cbase instanceof COSObject) {
COSObjectKey key = new COSObjectKey((COSObject) cbase);
COSObject obj = cDoc.getObjectFromPool(key);
if (obj == null) {
return null;
} else if (obj.getObject() instanceof COSNumber) {
return ((COSNumber) obj.getObject()).floatValue();
} else {
return null;
}
} else if (cbase instanceof COSNumber) {
return ((COSNumber) cbase).floatValue();
} else {
return null;
}
}
use of org.apache.pdfbox.cos.COSObjectKey in project pdfbox by apache.
the class COSUtils method isString.
/**
* return true if the elt is a COSString or a COSName or a reference to it.
*
* @param elt the object to check.
* @param doc the document.
* @return true if the object is a COSString or a COSName or a reference to it.
*/
public static boolean isString(COSBase elt, COSDocument doc) {
if (elt instanceof COSObject) {
COSObjectKey key = new COSObjectKey((COSObject) elt);
COSObject obj = doc.getObjectFromPool(key);
return (obj != null && (obj.getObject() instanceof COSString || obj.getObject() instanceof COSName));
}
return (elt instanceof COSString || elt instanceof COSName);
}
Aggregations