Skip to content

Commit 100a6ca

Browse files
Fix incorrect check of xref validity which lead to the unnecessary xref rebuilt. Add log message on xref rebuilt
DEVSIX-605
1 parent 8dff7f5 commit 100a6ca

File tree

6 files changed

+45
-14
lines changed

6 files changed

+45
-14
lines changed

io/src/main/java/com/itextpdf/io/LogMessageConstant.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ public final class LogMessageConstant {
6969
*/
7070
public static final String ELEMENT_DOES_NOT_FIT_AREA = "Element does not fit current area. {0}";
7171

72+
public static final String EXCEPTION_WHILE_UPDATING_XMPMETADATA = "Exception while updating XmpMetadata";
73+
7274
/**
7375
* Log message.
7476
*/
@@ -179,5 +181,5 @@ public final class LogMessageConstant {
179181

180182
public static final String WRITER_ENCRYPTION_IS_IGNORED_PRESERVE = "Writer encryption will be ignored, because preservation of encryption is enabled. Document will preserve the original encryption (or will stay unencrypted)";
181183

182-
public static final String EXCEPTION_WHILE_UPDATING_XMPMETADATA = "Exception while updating XmpMetadata";
184+
public static final String XREF_ERROR = "Error occurred while reading cross reference table. Cross reference table will be rebuilt.";
183185
}

kernel/src/main/java/com/itextpdf/kernel/PdfException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ public class PdfException extends RuntimeException {
152152
public static final String InvalidPageStructurePagesPagesMustBePdfDictionary = "invalid.page.structure.pages.must.be.pdfdictionary";
153153
public static final String InvalidRangeArray = "invalid.range.array";
154154
public static final String InvalidOffsetForObject1 = "invalid.offset.for.object {0}";
155-
public static final String InvalidXrefSection = "invalid.xref.section";
156155
public static final String InvalidXrefStream = "invalid.xref.stream";
156+
public static final String InvalidXrefTable = "invalid.xref.table";
157157
public static final String IoException = "io.exception";
158158
public static final String IsNotAnAcceptableValueForTheField = "{0}.is.not.an.acceptable.value.for.the.field.{1}";
159159
public static final String IsNotWmfImage = "is.not.wmf.image";

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfIndirectReference.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,19 +151,19 @@ public int getObjStreamNumber() {
151151
/**
152152
* Gets refersTo object offset in a document.
153153
*
154-
* @return object offset in a document. If refersTo object is in object stream then 0.
154+
* @return object offset in a document. If refersTo object is in object stream then -1.
155155
*/
156156
public long getOffset() {
157-
return objectStreamNumber == 0 ? offsetOrIndex : 0;
157+
return objectStreamNumber == 0 ? offsetOrIndex : -1;
158158
}
159159

160160
/**
161161
* Gets refersTo object index in the object stream.
162162
*
163-
* @return object index in a document. If refersTo object is not in object stream then 0.
163+
* @return object index in a document. If refersTo object is not in object stream then -1.
164164
*/
165165
public int getIndex() {
166-
return objectStreamNumber == 0 ? 0 : (int)offsetOrIndex;
166+
return objectStreamNumber == 0 ? -1 : (int)offsetOrIndex;
167167
}
168168

169169
@Override

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ This file is part of the iText (R) project.
5353
import com.itextpdf.io.source.RandomAccessSourceFactory;
5454
import com.itextpdf.io.source.WindowRandomAccessSource;
5555
import com.itextpdf.kernel.PdfException;
56-
import com.itextpdf.kernel.pdf.filters.DoNothingFilter;
5756
import com.itextpdf.kernel.pdf.filters.IFilterHandler;
5857
import com.itextpdf.kernel.pdf.filters.FilterHandlers;
5958

@@ -451,6 +450,9 @@ protected void readPdf() throws IOException {
451450
try {
452451
readXref();
453452
} catch (RuntimeException ex) {
453+
Logger logger = LoggerFactory.getLogger(PdfReader.class);
454+
logger.error(LogMessageConstant.XREF_ERROR, ex);
455+
454456
rebuildXref();
455457
}
456458
readDecryptObj();
@@ -711,14 +713,18 @@ protected void readXref() throws IOException {
711713
tokens.seek(startxref);
712714
trailer2 = readXrefSection();
713715
}
716+
717+
Integer xrefSize = trailer.getAsInt(PdfName.Size);
718+
if (xrefSize == null || xrefSize != pdfDocument.getXref().size()) {
719+
throw new PdfException(PdfException.InvalidXrefTable);
720+
}
714721
}
715722

716723
protected PdfDictionary readXrefSection() throws IOException {
717724
tokens.nextValidToken();
718725
if (!tokens.tokenValueEqualsTo(PdfTokenizer.Xref))
719726
tokens.throwError(PdfException.XrefSubsectionNotFound);
720727
PdfXrefTable xref = pdfDocument.getXref();
721-
int end = 0;
722728
while (true) {
723729
tokens.nextValidToken();
724730
if (tokens.tokenValueEqualsTo(PdfTokenizer.Trailer)) {
@@ -732,7 +738,7 @@ protected PdfDictionary readXrefSection() throws IOException {
732738
if (tokens.getTokenType() != PdfTokenizer.TokenType.Number) {
733739
tokens.throwError(PdfException.NumberOfEntriesInThisXrefSubsectionNotFound);
734740
}
735-
end = tokens.getIntValue() + start;
741+
int end = tokens.getIntValue() + start;
736742
for (int num = start; num < end; num++) {
737743
tokens.nextValidToken();
738744
long pos = tokens.getLongValue();
@@ -764,11 +770,6 @@ protected PdfDictionary readXrefSection() throws IOException {
764770
}
765771
}
766772
PdfDictionary trailer = (PdfDictionary) readObject(false);
767-
PdfNumber xrefSize = (PdfNumber) trailer.get(PdfName.Size);
768-
if (xrefSize == null || (xrefSize.intValue() != end && end > 0)) {
769-
throw new PdfException(PdfException.InvalidXrefSection);
770-
}
771-
772773
PdfObject xrs = trailer.get(PdfName.XRefStm);
773774
if (xrs != null && xrs.getType() == PdfObject.NUMBER) {
774775
int loc = ((PdfNumber) xrs).intValue();

kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ public void pagesTest10() throws IOException {
666666
}
667667

668668
@Test
669+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
669670
public void correctSimpleDoc1() throws IOException {
670671
String filename = sourceFolder + "correctSimpleDoc1.pdf";
671672

@@ -702,6 +703,7 @@ public void correctSimpleDoc2() throws IOException {
702703
}
703704

704705
@Test
706+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
705707
public void correctSimpleDoc3() throws IOException {
706708
String filename = sourceFolder + "correctSimpleDoc3.pdf";
707709

@@ -738,6 +740,7 @@ public void correctSimpleDoc4() throws IOException {
738740
}
739741

740742
@Test
743+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
741744
public void fixPdfTest01() throws IOException {
742745
String filename = sourceFolder + "OnlyTrailer.pdf";
743746

@@ -820,6 +823,7 @@ public void fixPdfTest04() throws IOException {
820823
}
821824

822825
@Test
826+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
823827
public void fixPdfTest05() throws IOException {
824828
String filename = sourceFolder + "CompressionWrongShift.pdf";
825829

@@ -873,6 +877,7 @@ public void fixPdfTest07() throws IOException {
873877
}
874878

875879
@Test
880+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
876881
public void fixPdfTest08() throws IOException {
877882
String filename = sourceFolder + "XRefSectionWithFreeReferences2.pdf";
878883

@@ -898,6 +903,7 @@ public void fixPdfTest08() throws IOException {
898903
}
899904

900905
@Test
906+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
901907
public void fixPdfTest09() throws IOException {
902908
String filename = sourceFolder + "XRefSectionWithFreeReferences3.pdf";
903909

@@ -950,6 +956,7 @@ public void fixPdfTest10() throws IOException {
950956
}
951957

952958
@Test
959+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
953960
public void fixPdfTest11() throws IOException {
954961
String filename = sourceFolder + "XRefSectionWithoutSize.pdf";
955962

@@ -971,6 +978,7 @@ public void fixPdfTest11() throws IOException {
971978
}
972979

973980
@Test
981+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
974982
public void fixPdfTest12() throws IOException {
975983
String filename = sourceFolder + "XRefWithBreaks.pdf";
976984

@@ -1061,6 +1069,7 @@ public void fixPdfTest14() throws IOException {
10611069
}
10621070

10631071
@Test
1072+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
10641073
public void fixPdfTest15() throws IOException {
10651074
String filename = sourceFolder + "XRefWithInvalidGenerations3.pdf";
10661075

@@ -1105,6 +1114,7 @@ public void fixPdfTest16() throws IOException {
11051114
}
11061115

11071116
@Test
1117+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
11081118
public void fixPdfTest17() throws IOException {
11091119
String filename = sourceFolder + "XrefWithNullOffsets.pdf";
11101120

@@ -1226,6 +1236,7 @@ public void appendModeWith10PagesWithCompression() throws IOException {
12261236
}
12271237

12281238
@Test
1239+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
12291240
public void appendModeWith10PagesFix1() throws IOException {
12301241
String filename = sourceFolder + "10PagesDocumentAppendedFix1.pdf";
12311242

@@ -1252,6 +1263,7 @@ public void appendModeWith10PagesFix1() throws IOException {
12521263
}
12531264

12541265
@Test
1266+
@LogMessages(messages = @LogMessage(messageTemplate = LogMessageConstant.XREF_ERROR, count = 1))
12551267
public void appendModeWith10PagesFix2() throws IOException {
12561268
String filename = sourceFolder + "10PagesDocumentAppendedFix2.pdf";
12571269

@@ -1496,6 +1508,22 @@ public void zeroUpdateTest() throws IOException {
14961508
pdfDoc.close();
14971509
}
14981510

1511+
@Test
1512+
public void incrementalUpdateWithOnlyZeroObjectUpdate() throws IOException {
1513+
String filename = sourceFolder + "pdfReferenceUpdated.pdf";
1514+
1515+
FileInputStream fis = new FileInputStream(filename);
1516+
PdfReader reader = new PdfReader(fis);
1517+
PdfDocument pdfDoc = new PdfDocument(reader);
1518+
1519+
Assert.assertFalse(reader.hasFixedXref());
1520+
Assert.assertFalse(reader.hasRebuiltXref());
1521+
1522+
// problem that is tested here originally was found because the StructTreeRoot dictionary wasn't read
1523+
Assert.assertTrue(pdfDoc.isTagged());
1524+
pdfDoc.close();
1525+
}
1526+
14991527

15001528
private boolean objectTypeEqualTo(PdfObject object, PdfName type) {
15011529
PdfName objectType = ((PdfDictionary)object).getAsName(PdfName.Type);

0 commit comments

Comments
 (0)