final Set<Long> addedObjects = new HashSet<>(); addExcludedToList(excludeObjects, dict, parsedObjects); addNewToList(toBeParsedList, dict.getValues(), addedObjects); addNewToList(toBeParsedList, ((COSDictionary) baseObj).getValues(), addedObjects); addNewToList(toBeParsedList, cosBase, addedObjects); long objId = getObjectId(obj); COSObjectKey objKey = new COSObjectKey(obj.getObjectNumber(), obj.getGenerationNumber()); if (fileOffset == null && isLenient) Map<COSObjectKey, Long> bfCOSObjectKeyOffsets = getBFCOSObjectOffsets(); fileOffset = bfCOSObjectKeyOffsets.get(objKey); if (fileOffset != null) Map<COSObjectKey, Long> bfCOSObjectKeyOffsets = getBFCOSObjectOffsets(); fileOffset = bfCOSObjectKeyOffsets.get(key); if (fileOffset != null) COSBase parsedObj = parseObjectDynamically(obj, false); if (parsedObj != null) addNewToList(toBeParsedList, parsedObj, addedObjects); parsedObjects.add(getObjectId(obj));
bfSearchForLastEOFMarker(); bfSearchCOSObjectKeyOffsets = new HashMap<>(); long originOffset = source.getPosition(); int nextChar = source.read(); currentOffset++; if (isWhitespace(nextChar) && isString(OBJ_MARKER)) int genID = source.peek(); if (isDigit(genID)) if (isWhitespace()) while (tempOffset > MINIMUM_SEARCH_OFFSET && isWhitespace()) while (tempOffset > MINIMUM_SEARCH_OFFSET && isDigit()) long objectId = readObjectNumber(); if (lastObjOffset > 0) else if (nextChar == 'e' && isString(endobjString)) continue; if (isString(endobjRemainingString))
long startXRefOffset = getStartxrefOffset(); if (startXRefOffset > -1) trailer = parseXref(startXRefOffset); rebuildTrailer = isLenient(); if (isLenient()) rebuildTrailer = isLenient(); trailer = rebuildTrailer(); prepareDecryption(); if (bfSearchCOSObjectKeyOffsets != null && !bfSearchCOSObjectKeyOffsets.isEmpty()) bfSearchForObjStreams();
skipSpaces(); if (source.peek() == X && isString(XREF_TABLE)) if (checkXRefStreamOffset(startXRefOffset)) return calculateXRefFixedOffset(startXRefOffset);
bfSearchForXRefTables(); bfSearchForXRefStreams(); long newOffsetTable = searchNearestValue(bfSearchXRefTablesOffsets, xrefOffset); long newOffsetStream = searchNearestValue(bfSearchXRefStreamsOffsets, xrefOffset);
bfSearchForObjects(); if (bfSearchCOSObjectKeyOffsets != null) getDocument().setTrailer(trailer); if (!bfSearchForTrailer(trailer)) COSDictionary dictionary = retrieveCOSDictionary(entry.getKey(), entry.getValue()); if (dictionary == null) if (isCatalog(dictionary)) else if (isInfo(dictionary))
bfSearchForLastEOFMarker(); bfSearchCOSObjectKeyOffsets = new HashMap<>(); long originOffset = source.getPosition(); int nextChar = source.read(); currentOffset++; if (nextChar == ' ' && isString(OBJ_MARKER)) int genID = source.peek(); if (isDigit(genID)) if (isSpace()) while (tempOffset > MINIMUM_SEARCH_OFFSET && isSpace()) while (tempOffset > MINIMUM_SEARCH_OFFSET && isDigit()) long objectId = readObjectNumber(); if (lastObjOffset > 0) else if (nextChar == 'e' && isString(endobjString)) continue; if (isString(endobjRemainingString)) bfSearchForObjStreams();
bfSearchForObjects(); if (bfSearchCOSObjectKeyOffsets != null) getDocument().setTrailer(trailer); boolean searchForObjStreamsDone = false; if (!bfSearchForTrailer(trailer)) if (!searchForTrailerItems(trailer)) bfSearchForObjStreams(); searchForObjStreamsDone = true; searchForTrailerItems(trailer); prepareDecryption(); if (!searchForObjStreamsDone) bfSearchForObjStreams();
bfSearchForObjects(); if (bfSearchCOSObjectKeyOffsets != null && !bfSearchCOSObjectKeyOffsets.isEmpty()) parseFileObject(offsetOrObjstmObNr, objKey, pdfObject); parseObjectStream((int) -offsetOrObjstmObNr);
/** * Check the XRef table by dereferencing all objects and fixing the offset if necessary. * * @throws IOException if something went wrong. */ private void checkXrefOffsets() throws IOException { // repair mode isn't available in non-lenient mode if (!isLenient) { return; } Map<COSObjectKey, Long> xrefOffset = xrefTrailerResolver.getXrefTable(); if (!validateXrefOffsets(xrefOffset)) { bfSearchForObjects(); if (bfSearchCOSObjectKeyOffsets != null && !bfSearchCOSObjectKeyOffsets.isEmpty()) { LOG.debug("Replaced read xref table with the results of a brute force search"); xrefOffset.clear(); xrefOffset.putAll(bfSearchCOSObjectKeyOffsets); } } }
/** * Adds all from newObjects to toBeParsedList if it is not an COSObject or * we didn't add this COSObject already (checked via addedObjects). */ private void addNewToList(final Queue<COSBase> toBeParsedList, final Collection<COSBase> newObjects, final Set<Long> addedObjects) { for (COSBase newObject : newObjects) { addNewToList(toBeParsedList, newObject, addedObjects); } }
/** * Try to find a fixed offset for the given xref table/stream. * * @param objectOffset the given offset where to look at * @return the fixed offset * * @throws IOException if something went wrong */ private long calculateXRefFixedOffset(long objectOffset) throws IOException { if (objectOffset < 0) { LOG.error("Invalid object offset " + objectOffset + " when searching for a xref table/stream"); return 0; } // start a brute force search for all xref tables and try to find the offset we are looking for long newOffset = bfSearchForXRef(objectOffset); if (newOffset > -1) { LOG.debug("Fixed reference for xref table/stream " + objectOffset + " -> " + newOffset); return newOffset; } LOG.error("Can't find the object xref table/stream at offset " + objectOffset); return 0; }
private Map<COSObjectKey, Long> getBFCOSObjectOffsets() throws IOException { if (bfSearchCOSObjectKeyOffsets == null) { bfSearchForObjects(); } return bfSearchCOSObjectKeyOffsets; }
bfSearchForObjects(); if (bfSearchCOSObjectKeyOffsets != null) getDocument().setTrailer(trailer); boolean searchForObjStreamsDone = false; if (!bfSearchForTrailer(trailer)) if (!searchForTrailerItems(trailer)) bfSearchForObjStreams(); searchForObjStreamsDone = true; searchForTrailerItems(trailer); prepareDecryption(); if (!searchForObjStreamsDone) bfSearchForObjStreams();
skipSpaces(); if (source.peek() == X && isString(XREF_TABLE)) if (checkXRefStreamOffset(startXRefOffset)) return calculateXRefFixedOffset(startXRefOffset, false);
if (!streamsOnly) bfSearchForXRefTables(); bfSearchForXRefStreams(); if (!streamsOnly && bfSearchXRefTablesOffsets != null) newOffsetTable = searchNearestValue(bfSearchXRefTablesOffsets, xrefOffset); newOffsetStream = searchNearestValue(bfSearchXRefStreamsOffsets, xrefOffset);
/** * Adds all from newObjects to toBeParsedList if it is not an COSObject or * we didn't add this COSObject already (checked via addedObjects). */ private void addNewToList(final Queue<COSBase> toBeParsedList, final Collection<COSBase> newObjects, final Set<Long> addedObjects) { for (COSBase newObject : newObjects) { addNewToList(toBeParsedList, newObject, addedObjects); } }
/** * Try to find a fixed offset for the given xref table/stream. * * @param objectOffset the given offset where to look at * @param streamsOnly search for xref streams only * @return the fixed offset * * @throws IOException if something went wrong */ private long calculateXRefFixedOffset(long objectOffset, boolean streamsOnly) throws IOException { if (objectOffset < 0) { LOG.error("Invalid object offset " + objectOffset + " when searching for a xref table/stream"); return 0; } // start a brute force search for all xref tables and try to find the offset we are looking for long newOffset = bfSearchForXRef(objectOffset, streamsOnly); if (newOffset > -1) { LOG.debug("Fixed reference for xref table/stream " + objectOffset + " -> " + newOffset); return newOffset; } LOG.error("Can't find the object xref table/stream at offset " + objectOffset); return 0; }
private Map<COSObjectKey, Long> getBFCOSObjectOffsets() throws IOException { if (bfSearchCOSObjectKeyOffsets == null) { bfSearchForObjects(); } return bfSearchCOSObjectKeyOffsets; }
final Set<Long> addedObjects = new HashSet<>(); addExcludedToList(excludeObjects, dict, parsedObjects); addNewToList(toBeParsedList, dict.getValues(), addedObjects); addNewToList(toBeParsedList, ((COSDictionary) baseObj).getValues(), addedObjects); addNewToList(toBeParsedList, cosBase, addedObjects); long objId = getObjectId(obj); COSObjectKey objKey = new COSObjectKey(obj.getObjectNumber(), obj.getGenerationNumber()); if (fileOffset == null && isLenient) Map<COSObjectKey, Long> bfCOSObjectKeyOffsets = getBFCOSObjectOffsets(); fileOffset = bfCOSObjectKeyOffsets.get(objKey); if (fileOffset != null) Map<COSObjectKey, Long> bfCOSObjectKeyOffsets = getBFCOSObjectOffsets(); fileOffset = bfCOSObjectKeyOffsets.get(key); if (fileOffset != null) COSBase parsedObj = parseObjectDynamically(obj, false); if (parsedObj != null) addNewToList(toBeParsedList, parsedObj, addedObjects); parsedObjects.add(getObjectId(obj));