diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java b/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java index 31b9a341bc6..f79597cc15b 100644 --- a/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java +++ b/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java @@ -1159,6 +1159,7 @@ private boolean validateXrefOffsets(Map xrefOffset) throws I return true; } Map correctedKeys = new HashMap<>(); + HashSet validKeys = new HashSet<>(); for (Entry objectEntry : xrefOffset.entrySet()) { COSObjectKey objectKey = objectEntry.getKey(); @@ -1178,13 +1179,24 @@ else if (foundObjectKey != objectKey) { // Generation was fixed - need to update map later, after iteration correctedKeys.put(objectKey, foundObjectKey); + } else { + validKeys.add(objectKey); } } } - for (Entry correctedKeyEntry : correctedKeys.entrySet()) - { - xrefOffset.put(correctedKeyEntry.getValue(), - xrefOffset.remove(correctedKeyEntry.getKey())); + Map correctedPointers = new HashMap(); + for (Entry correctedKeyEntry : correctedKeys.entrySet()) { + if (!validKeys.contains(correctedKeyEntry.getValue())) { + // Only replace entries, if the original entry does not point to a valid object + correctedPointers.put(correctedKeyEntry.getValue(), xrefOffset.get(correctedKeyEntry.getKey())); + } + } + for (Entry correctedKeyEntry : correctedKeys.entrySet()) { + // remove old invalid, as some might not be replaced + xrefOffset.remove(correctedKeyEntry.getKey()); + } + for (Entry pointer : correctedPointers.entrySet()) { + xrefOffset.put(pointer.getKey(), pointer.getValue()); } return true; } @@ -1235,19 +1247,23 @@ private COSObjectKey findObjectKey(COSObjectKey objectKey, long offset) throws I { source.seek(offset); // try to read the given object/generation number - if (objectKey.getNumber() == readObjectNumber()) + long foundObjectNumber = readObjectNumber(); + if(objectKey.getNumber() != foundObjectNumber){ + LOG.warn("found wrong object number. expected [" + objectKey.getNumber() +"] found ["+ foundObjectNumber + "]"); + if(!isLenient) return null; + else objectKey = new COSObjectKey(foundObjectNumber, objectKey.getGeneration()); + } + + int genNumber = readGenerationNumber(); + // finally try to read the object marker + readExpectedString(OBJ_MARKER, true); + if (genNumber == objectKey.getGeneration()) { - int genNumber = readGenerationNumber(); - // finally try to read the object marker - readExpectedString(OBJ_MARKER, true); - if (genNumber == objectKey.getGeneration()) - { - return objectKey; - } - else if (isLenient && genNumber > objectKey.getGeneration()) - { - return new COSObjectKey(objectKey.getNumber(), genNumber); - } + return objectKey; + } + else if (isLenient && genNumber > objectKey.getGeneration()) + { + return new COSObjectKey(objectKey.getNumber(), genNumber); } } catch (IOException exception)