You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2017/05/11 05:43:28 UTC
svn commit: r1794782 -
/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java
Author: lehmi
Date: Thu May 11 05:43:28 2017
New Revision: 1794782
URL: http://svn.apache.org/viewvc?rev=1794782&view=rev
Log:
PDFBOX-3788: revert former changes due to a regression
Modified:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java?rev=1794782&r1=1794781&r2=1794782&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdfparser/COSParser.java Thu May 11 05:43:28 2017
@@ -313,13 +313,9 @@ public class COSParser extends BaseParse
document.setTrailer(trailer);
document.setIsXRefStream(XRefType.STREAM == xrefTrailerResolver.getXrefType());
// check the offsets of all referenced objects
- Map<COSObjectKey, Long> xrefOffset = xrefTrailerResolver.getXrefTable();
- if (isLenient && !validateXrefOffsets(xrefOffset))
- {
- throw new IOException("Invalid object reference found");
- }
+ checkXrefOffsets();
// copy xref table
- document.addXRefTable(xrefOffset);
+ document.addXRefTable(xrefTrailerResolver.getXrefTable());
return trailer;
}
@@ -1296,6 +1292,77 @@ public class COSParser extends BaseParse
}
/**
+ * 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())
+ {
+ List<COSObjectKey> objStreams = new ArrayList<COSObjectKey>();
+ // find all object streams
+ for (COSObjectKey key : xrefOffset.keySet())
+ {
+ Long offset = xrefOffset.get(key);
+ if (offset != null && offset < 0)
+ {
+ COSObjectKey objStream = new COSObjectKey(-offset, 0);
+ if (!objStreams.contains(objStream))
+ {
+ objStreams.add(new COSObjectKey(-offset, 0));
+ }
+ }
+ }
+ // remove all found object streams
+ if (!objStreams.isEmpty())
+ {
+ for (COSObjectKey key : objStreams)
+ {
+ if (bfSearchCOSObjectKeyOffsets.containsKey(key))
+ {
+ // remove all parsed objects which are part of an object stream
+ Set<Long> objects = xrefTrailerResolver
+ .getContainedObjectNumbers((int) (key.getNumber()));
+ for (Long objNr : objects)
+ {
+ COSObjectKey streamObjectKey = new COSObjectKey(objNr, 0);
+ Long streamObjectOffset = bfSearchCOSObjectKeyOffsets
+ .get(streamObjectKey);
+ if (streamObjectOffset != null && streamObjectOffset > 0)
+ {
+ bfSearchCOSObjectKeyOffsets.remove(streamObjectKey);
+ }
+ }
+ }
+ else
+ {
+ // remove all objects which are part of an object stream which wasn't found
+ Set<Long> objects = xrefTrailerResolver
+ .getContainedObjectNumbers((int) (key.getNumber()));
+ for (Long objNr : objects)
+ {
+ xrefOffset.remove(new COSObjectKey(objNr, 0));
+ }
+ }
+ }
+ }
+ LOG.debug("Replaced read xref table with the results of a brute force search");
+ xrefOffset.putAll(bfSearchCOSObjectKeyOffsets);
+ }
+ }
+ }
+
+ /**
* Check if the given object can be found at the given offset.
*
* @param objectKey the object we are looking for