@@ -53,7 +53,6 @@ This file is part of the iText (R) project.
53
53
import com .itextpdf .kernel .exceptions .KernelExceptionMessageConstant ;
54
54
import com .itextpdf .kernel .pdf .filters .FlateDecodeFilter ;
55
55
import com .itextpdf .commons .utils .MessageFormatUtil ;
56
-
57
56
import org .slf4j .Logger ;
58
57
import org .slf4j .LoggerFactory ;
59
58
import java .io .IOException ;
@@ -67,6 +66,7 @@ public class PdfOutputStream extends OutputStream<PdfOutputStream> {
67
66
private static final byte [] closeDict = ByteUtils .getIsoBytes (">>" );
68
67
private static final byte [] endIndirect = ByteUtils .getIsoBytes (" R" );
69
68
private static final byte [] endIndirectWithZeroGenNr = ByteUtils .getIsoBytes (" 0 R" );
69
+ private static final Logger LOGGER = LoggerFactory .getLogger (PdfOutputStream .class );
70
70
71
71
/**
72
72
* Document associated with PdfOutputStream.
@@ -181,8 +181,7 @@ private void write(PdfDictionary pdfDictionary) {
181
181
write (key );
182
182
PdfObject value = pdfDictionary .get (key , false );
183
183
if (value == null ) {
184
- Logger logger = LoggerFactory .getLogger (PdfOutputStream .class );
185
- logger .warn (MessageFormatUtil .format (IoLogMessageConstant .INVALID_KEY_VALUE_KEY_0_HAS_NULL_VALUE , key ));
184
+ LOGGER .warn (MessageFormatUtil .format (IoLogMessageConstant .INVALID_KEY_VALUE_KEY_0_HAS_NULL_VALUE , key ));
186
185
value = PdfNull .PDF_NULL ;
187
186
}
188
187
if ((value .getType () == PdfObject .NUMBER
@@ -213,14 +212,12 @@ private void write(PdfIndirectReference indirectReference) {
213
212
throw new PdfException (KernelExceptionMessageConstant .PDF_INDIRECT_OBJECT_BELONGS_TO_OTHER_PDF_DOCUMENT );
214
213
}
215
214
if (indirectReference .isFree ()) {
216
- Logger logger = LoggerFactory .getLogger (PdfOutputStream .class );
217
- logger .error (IoLogMessageConstant .FLUSHED_OBJECT_CONTAINS_FREE_REFERENCE );
215
+ LOGGER .error (IoLogMessageConstant .FLUSHED_OBJECT_CONTAINS_FREE_REFERENCE );
218
216
write (PdfNull .PDF_NULL );
219
217
} else if (indirectReference .refersTo == null
220
218
&& (indirectReference .checkState (PdfObject .MODIFIED ) || indirectReference .getReader () == null
221
219
|| !(indirectReference .getOffset () > 0 || indirectReference .getIndex () >= 0 ))) {
222
- Logger logger = LoggerFactory .getLogger (PdfOutputStream .class );
223
- logger .error (IoLogMessageConstant .FLUSHED_OBJECT_CONTAINS_REFERENCE_WHICH_NOT_REFER_TO_ANY_OBJECT );
220
+ LOGGER .error (IoLogMessageConstant .FLUSHED_OBJECT_CONTAINS_REFERENCE_WHICH_NOT_REFER_TO_ANY_OBJECT );
224
221
write (PdfNull .PDF_NULL );
225
222
} else if (indirectReference .getGenNumber () == 0 ) {
226
223
writeInteger (indirectReference .getObjNumber ()).
@@ -339,7 +336,8 @@ private void write(PdfStream pdfStream) {
339
336
assert pdfStream .getOutputStream () != null : "PdfStream lost OutputStream" ;
340
337
ByteArrayOutputStream byteArrayStream ;
341
338
try {
342
- if (toCompress && !containsFlateFilter (pdfStream ) && (allowCompression || userDefinedCompression )) {
339
+ if (toCompress && !containsFlateFilter (pdfStream ) && decodeParamsArrayNotFlushed (pdfStream )
340
+ && (allowCompression || userDefinedCompression )) {
343
341
// compress
344
342
updateCompressionFilter (pdfStream );
345
343
byteArrayStream = new ByteArrayOutputStream ();
@@ -390,70 +388,86 @@ private void write(PdfStream pdfStream) {
390
388
protected boolean checkEncryption (PdfStream pdfStream ) {
391
389
if (crypto == null || (crypto .isEmbeddedFilesOnly () && !document .doesStreamBelongToEmbeddedFile (pdfStream ))) {
392
390
return false ;
393
- } else if (isXRefStream (pdfStream )) {
391
+ }
392
+ if (isXRefStream (pdfStream )) {
394
393
// The cross-reference stream shall not be encrypted
395
394
return false ;
396
- } else {
397
- PdfObject filter = pdfStream .get (PdfName .Filter , true );
398
- if (filter != null ) {
399
- if (PdfName .Crypt .equals (filter )) {
400
- return false ;
401
- } else if (filter .getType () == PdfObject .ARRAY ) {
402
- PdfArray filters = (PdfArray ) filter ;
403
- if (!filters .isEmpty () && PdfName .Crypt .equals (filters .get (0 , true ))) {
404
- return false ;
405
- }
406
- }
407
- }
395
+ }
396
+ PdfObject filter = pdfStream .get (PdfName .Filter , true );
397
+ if (filter == null ) {
408
398
return true ;
409
399
}
400
+ if (filter .isFlushed ()) {
401
+ IndirectFilterUtils .throwFlushedFilterException (pdfStream );
402
+ }
403
+ if (PdfName .Crypt .equals (filter )) {
404
+ return false ;
405
+ }
406
+ if (filter .getType () == PdfObject .ARRAY ) {
407
+ PdfArray filters = (PdfArray ) filter ;
408
+ if (filters .isEmpty ()) {
409
+ return true ;
410
+ }
411
+ if (filters .get (0 ).isFlushed ()) {
412
+ IndirectFilterUtils .throwFlushedFilterException (pdfStream );
413
+ }
414
+ return !PdfName .Crypt .equals (filters .get (0 , true ));
415
+ }
416
+ return true ;
410
417
}
411
418
412
419
protected boolean containsFlateFilter (PdfStream pdfStream ) {
413
420
PdfObject filter = pdfStream .get (PdfName .Filter );
414
- if (filter != null ) {
415
- if (filter .getType () == PdfObject .NAME ) {
416
- if (PdfName .FlateDecode .equals (filter )) {
417
- return true ;
418
- }
419
- } else if (filter .getType () == PdfObject .ARRAY ) {
420
- if (((PdfArray ) filter ).contains (PdfName .FlateDecode ))
421
- return true ;
422
- } else {
423
- throw new PdfException (KernelExceptionMessageConstant .FILTER_IS_NOT_A_NAME_OR_ARRAY );
421
+ if (filter == null ) {
422
+ return false ;
423
+ }
424
+ if (filter .isFlushed ()) {
425
+ IndirectFilterUtils .logFilterWasAlreadyFlushed (LOGGER , pdfStream );
426
+ return true ;
427
+ }
428
+ if (filter .getType () != PdfObject .NAME && filter .getType () != PdfObject .ARRAY ) {
429
+ throw new PdfException (KernelExceptionMessageConstant .FILTER_IS_NOT_A_NAME_OR_ARRAY );
430
+ }
431
+ if (filter .getType () == PdfObject .NAME ) {
432
+ return PdfName .FlateDecode .equals (filter );
433
+ }
434
+ for (PdfObject obj : (PdfArray ) filter ) {
435
+ if (obj .isFlushed ()) {
436
+ IndirectFilterUtils .logFilterWasAlreadyFlushed (LOGGER , pdfStream );
437
+ return true ;
424
438
}
425
439
}
426
- return false ;
440
+ return (( PdfArray ) filter ). contains ( PdfName . FlateDecode ) ;
427
441
}
428
442
429
443
protected void updateCompressionFilter (PdfStream pdfStream ) {
430
444
PdfObject filter = pdfStream .get (PdfName .Filter );
431
445
if (filter == null ) {
432
446
pdfStream .put (PdfName .Filter , PdfName .FlateDecode );
447
+ return ;
448
+ }
449
+ PdfArray filters = new PdfArray ();
450
+ filters .add (PdfName .FlateDecode );
451
+ if (filter instanceof PdfArray ) {
452
+ filters .addAll ((PdfArray ) filter );
433
453
} else {
434
- PdfArray filters = new PdfArray ();
435
- filters .add (PdfName .FlateDecode );
436
- if (filter instanceof PdfArray ) {
437
- filters .addAll ((PdfArray ) filter );
454
+ filters .add (filter );
455
+ }
456
+ PdfObject decodeParms = pdfStream .get (PdfName .DecodeParms );
457
+ if (decodeParms != null ) {
458
+ if (decodeParms instanceof PdfDictionary ) {
459
+ PdfArray array = new PdfArray ();
460
+ array .add (new PdfNull ());
461
+ array .add (decodeParms );
462
+ pdfStream .put (PdfName .DecodeParms , array );
463
+ } else if (decodeParms instanceof PdfArray ) {
464
+ ((PdfArray ) decodeParms ).add (0 , new PdfNull ());
438
465
} else {
439
- filters .add (filter );
440
- }
441
- PdfObject decodeParms = pdfStream .get (PdfName .DecodeParms );
442
- if (decodeParms != null ) {
443
- if (decodeParms instanceof PdfDictionary ) {
444
- PdfArray array = new PdfArray ();
445
- array .add (new PdfNull ());
446
- array .add (decodeParms );
447
- pdfStream .put (PdfName .DecodeParms , array );
448
- } else if (decodeParms instanceof PdfArray ) {
449
- ((PdfArray ) decodeParms ).add (0 , new PdfNull ());
450
- } else {
451
- throw new PdfException (KernelExceptionMessageConstant .THIS_DECODE_PARAMETER_TYPE_IS_NOT_SUPPORTED )
452
- .setMessageParams (decodeParms .getClass ().toString ());
453
- }
466
+ throw new PdfException (KernelExceptionMessageConstant .THIS_DECODE_PARAMETER_TYPE_IS_NOT_SUPPORTED )
467
+ .setMessageParams (decodeParms .getClass ().toString ());
454
468
}
455
- pdfStream .put (PdfName .Filter , filters );
456
469
}
470
+ pdfStream .put (PdfName .Filter , filters );
457
471
}
458
472
459
473
protected byte [] decodeFlateBytes (PdfStream stream , byte [] bytes ) {
@@ -468,11 +482,20 @@ protected byte[] decodeFlateBytes(PdfStream stream, byte[] bytes) {
468
482
filterName = (PdfName ) filterObject ;
469
483
} else if (filterObject instanceof PdfArray ) {
470
484
filtersArray = (PdfArray ) filterObject ;
485
+ if (filtersArray .isFlushed ()) {
486
+ IndirectFilterUtils .logFilterWasAlreadyFlushed (LOGGER , stream );
487
+ return bytes ;
488
+ }
471
489
filterName = filtersArray .getAsName (0 );
472
490
} else {
473
491
throw new PdfException (KernelExceptionMessageConstant .FILTER_IS_NOT_A_NAME_OR_ARRAY );
474
492
}
475
493
494
+ if (filterName .isFlushed ()) {
495
+ IndirectFilterUtils .logFilterWasAlreadyFlushed (LOGGER , stream );
496
+ return bytes ;
497
+ }
498
+
476
499
if (!PdfName .FlateDecode .equals (filterName )) {
477
500
return bytes ;
478
501
}
@@ -483,6 +506,9 @@ protected byte[] decodeFlateBytes(PdfStream stream, byte[] bytes) {
483
506
PdfObject decodeParamsObject = stream .get (PdfName .DecodeParms );
484
507
if (decodeParamsObject == null ) {
485
508
decodeParams = null ;
509
+ } else if (decodeParamsObject .isFlushed ()) {
510
+ IndirectFilterUtils .logFilterWasAlreadyFlushed (LOGGER , stream );
511
+ return bytes ;
486
512
} else if (decodeParamsObject .getType () == PdfObject .DICTIONARY ) {
487
513
decodeParams = (PdfDictionary ) decodeParamsObject ;
488
514
} else if (decodeParamsObject .getType () == PdfObject .ARRAY ) {
@@ -493,6 +519,13 @@ protected byte[] decodeFlateBytes(PdfStream stream, byte[] bytes) {
493
519
.setMessageParams (decodeParamsObject .getClass ().toString ());
494
520
}
495
521
522
+ if (decodeParams != null && (decodeParams .isFlushed () || isFlushed (decodeParams , PdfName .Predictor )
523
+ || isFlushed (decodeParams , PdfName .Columns ) || isFlushed (decodeParams , PdfName .Colors ) || isFlushed (
524
+ decodeParams , PdfName .BitsPerComponent ))) {
525
+ IndirectFilterUtils .logFilterWasAlreadyFlushed (LOGGER , stream );
526
+ return bytes ;
527
+ }
528
+
496
529
// decode
497
530
byte [] res = FlateDecodeFilter .flateDecode (bytes , true );
498
531
if (res == null )
@@ -535,4 +568,21 @@ protected byte[] decodeFlateBytes(PdfStream stream, byte[] bytes) {
535
568
536
569
return bytes ;
537
570
}
571
+
572
+ private static boolean isFlushed (PdfDictionary dict , PdfName name ) {
573
+ PdfObject obj = dict .get (name );
574
+ return obj != null && obj .isFlushed ();
575
+ }
576
+
577
+ private static boolean decodeParamsArrayNotFlushed (PdfStream pdfStream ) {
578
+ PdfArray decodeParams = pdfStream .getAsArray (PdfName .DecodeParms );
579
+ if (decodeParams == null ) {
580
+ return true ;
581
+ }
582
+ if (decodeParams .isFlushed ()) {
583
+ IndirectFilterUtils .logFilterWasAlreadyFlushed (LOGGER , pdfStream );
584
+ return false ;
585
+ }
586
+ return true ;
587
+ }
538
588
}
0 commit comments