@@ -1307,6 +1307,7 @@ protected void fixXref() throws IOException {
1307
1307
}
1308
1308
}
1309
1309
1310
+
1310
1311
protected void rebuildXref () throws IOException {
1311
1312
xrefStm = false ;
1312
1313
hybridXref = false ;
@@ -1316,40 +1317,70 @@ protected void rebuildXref() throws IOException {
1316
1317
tokens .seek (0 );
1317
1318
trailer = null ;
1318
1319
ByteBuffer buffer = new ByteBuffer (24 );
1319
- PdfTokenizer lineTokenizer =
1320
- new PdfTokenizer (new RandomAccessFileOrArray (new ReusableRandomAccessSource (buffer )));
1321
- for (; ; ) {
1322
- long pos = tokens .getPosition ();
1323
- buffer .reset ();
1320
+ try (PdfTokenizer lineTokenizer = new PdfTokenizer (
1321
+ new RandomAccessFileOrArray (new ReusableRandomAccessSource (buffer )))) {
1322
+ Long trailerIndex = null ;
1324
1323
1325
- // added boolean because of mailing list issue (17 Feb. 2014)
1326
- if (!tokens .readLineSegment (buffer , true ))
1327
- break ;
1328
- if (buffer .get (0 ) == 't' ) {
1329
- if (!PdfTokenizer .checkTrailer (buffer ))
1330
- continue ;
1331
- tokens .seek (pos );
1332
- tokens .nextToken ();
1333
- pos = tokens .getPosition ();
1334
- try {
1335
- PdfDictionary dic = (PdfDictionary ) readObject (false );
1336
- if (dic .get (PdfName .Root , false ) != null )
1337
- trailer = dic ;
1338
- else
1339
- tokens .seek (pos );
1340
- } catch (Exception e ) {
1341
- tokens .seek (pos );
1324
+ for (; ; ) {
1325
+ long pos = tokens .getPosition ();
1326
+ buffer .reset ();
1327
+
1328
+ // added boolean because of mailing list issue (17 Feb. 2014)
1329
+ if (!tokens .readLineSegment (buffer , true )) {
1330
+ break ;
1342
1331
}
1343
- } else if (buffer .get (0 ) >= '0' && buffer .get (0 ) <= '9' ) {
1344
- int [] obj = PdfTokenizer .checkObjectStart (lineTokenizer );
1345
- if (obj == null )
1346
- continue ;
1347
- int num = obj [0 ];
1348
- int gen = obj [1 ];
1349
- if (xref .get (num ) == null || xref .get (num ).getGenNumber () <= gen ) {
1350
- xref .add (new PdfIndirectReference (pdfDocument , num , gen , pos ));
1332
+ if (buffer .get (0 ) == 't' ) {
1333
+ if (!PdfTokenizer .checkTrailer (buffer )) {
1334
+ continue ;
1335
+ }
1336
+ tokens .seek (pos );
1337
+ tokens .nextToken ();
1338
+ pos = tokens .getPosition ();
1339
+ if (isCurrentObjectATrailer ()) {
1340
+ // if the pdf is linearized it is possible that the trailer has been read
1341
+ // before the actual objects it refers to this causes the trailer to have
1342
+ // objects in READING state that's why we keep track of the position of the
1343
+ // trailer and then asign it when the whole pdf has been loaded
1344
+ trailerIndex = pos ;
1345
+ } else {
1346
+ tokens .seek (pos );
1347
+ }
1348
+ } else if (buffer .get (0 ) >= '0' && buffer .get (0 ) <= '9' ) {
1349
+ int [] obj = PdfTokenizer .checkObjectStart (lineTokenizer );
1350
+ if (obj == null ) {
1351
+ continue ;
1352
+ }
1353
+ int num = obj [0 ];
1354
+ int gen = obj [1 ];
1355
+ if (xref .get (num ) == null || xref .get (num ).getGenNumber () <= gen ) {
1356
+ xref .add (new PdfIndirectReference (pdfDocument , num , gen , pos ));
1357
+ }
1351
1358
}
1352
1359
}
1360
+ // now that the document has been read fully the underlying trailer references won't be
1361
+ // in READING state when the pdf has been linearised now we can assign the trailer
1362
+ // and it will have the right references
1363
+ setTrailerFromTrailerIndex (trailerIndex );
1364
+ }
1365
+ }
1366
+
1367
+ private boolean isCurrentObjectATrailer () {
1368
+ try {
1369
+ final PdfDictionary dic = (PdfDictionary ) readObject (false );
1370
+ return dic .get (PdfName .Root , false ) != null ;
1371
+ } catch (Exception e ) {
1372
+ return false ;
1373
+ }
1374
+ }
1375
+
1376
+ private void setTrailerFromTrailerIndex (Long trailerIndex ) throws IOException {
1377
+ if (trailerIndex == null ) {
1378
+ throw new PdfException (KernelExceptionMessageConstant .TRAILER_NOT_FOUND );
1379
+ }
1380
+ tokens .seek ((long )trailerIndex );
1381
+ final PdfDictionary dic = (PdfDictionary ) readObject (false );
1382
+ if (dic .get (PdfName .Root , false ) != null ) {
1383
+ trailer = dic ;
1353
1384
}
1354
1385
if (trailer == null ) {
1355
1386
throw new PdfException (KernelExceptionMessageConstant .TRAILER_NOT_FOUND );
0 commit comments