Skip to content

Commit b22c9cd

Browse files
BezrukovMiText-CI
authored andcommitted
Add Strictness level for PdfReader
DEVSIX-5094 Autoported commit. Original commit hash: [076595cb2]
1 parent cf68079 commit b22c9cd

File tree

5 files changed

+165
-26
lines changed

5 files changed

+165
-26
lines changed

itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfDocumentIdTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,18 @@ public virtual void ReadPdfWithNoIdTest() {
319319
NUnit.Framework.Assert.AreEqual(0, reader.GetOriginalFileId().Length);
320320
NUnit.Framework.Assert.AreEqual(0, reader.GetModifiedFileId().Length);
321321
}
322+
323+
[NUnit.Framework.Test]
324+
public virtual void ReadPdfWithNoIdAndConservativeReadingTest() {
325+
using (PdfReader reader = new PdfReader(sourceFolder + "pdfWithNoId.pdf").SetStrictnessLevel(PdfReader.StrictnessLevel
326+
.CONSERVATIVE)) {
327+
NUnit.Framework.Assert.That(() => {
328+
new PdfDocument(reader);
329+
}
330+
, NUnit.Framework.Throws.InstanceOf<PdfException>().With.Message.EqualTo(iText.IO.LogMessageConstant.DOCUMENT_IDS_ARE_CORRUPTED))
331+
;
332+
}
333+
}
322334
// @Test
323335
// public void appendModeTest() {
324336
// String originalId;

itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfDocumentTest.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ source product.
4444
using System.IO;
4545
using iText.IO.Image;
4646
using iText.IO.Source;
47+
using iText.Kernel;
4748
using iText.Kernel.Colors;
4849
using iText.Kernel.Geom;
4950
using iText.Kernel.Pdf.Annot;
@@ -448,6 +449,18 @@ public virtual void OpenDocumentWithInvalidCatalogVersionTest() {
448449
}
449450
}
450451

452+
[NUnit.Framework.Test]
453+
public virtual void OpenDocumentWithInvalidCatalogVersionAndConservativeStrictnessReadingTest() {
454+
using (PdfReader reader = new PdfReader(SOURCE_FOLDER + "sample-with-invalid-catalog-version.pdf").SetStrictnessLevel
455+
(PdfReader.StrictnessLevel.CONSERVATIVE)) {
456+
NUnit.Framework.Assert.That(() => {
457+
new PdfDocument(reader);
458+
}
459+
, NUnit.Framework.Throws.InstanceOf<PdfException>().With.Message.EqualTo(iText.IO.LogMessageConstant.DOCUMENT_VERSION_IN_CATALOG_CORRUPTED))
460+
;
461+
}
462+
}
463+
451464
private class IgnoreTagStructurePdfDocument : PdfDocument {
452465
internal IgnoreTagStructurePdfDocument(PdfReader reader)
453466
: base(reader) {

itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,32 +1956,9 @@ protected internal virtual void Open(PdfVersion newPdfVersion) {
19561956
}
19571957
pdfVersion = reader.headerPdfVersion;
19581958
trailer = new PdfDictionary(reader.trailer);
1959-
PdfArray id = reader.trailer.GetAsArray(PdfName.ID);
1960-
if (id != null) {
1961-
if (id.Size() == 2) {
1962-
originalDocumentId = id.GetAsString(0);
1963-
modifiedDocumentId = id.GetAsString(1);
1964-
}
1965-
if (originalDocumentId == null || modifiedDocumentId == null) {
1966-
ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.PdfDocument));
1967-
logger.Error(iText.IO.LogMessageConstant.DOCUMENT_IDS_ARE_CORRUPTED);
1968-
}
1969-
}
1959+
ReadDocumentIds();
19701960
catalog = new PdfCatalog((PdfDictionary)trailer.Get(PdfName.Root, true));
1971-
if (catalog.GetPdfObject().ContainsKey(PdfName.Version)) {
1972-
// The version of the PDF specification to which the document conforms (for example, 1.4)
1973-
// if later than the version specified in the file's header
1974-
try {
1975-
PdfVersion catalogVersion = PdfVersion.FromPdfName(catalog.GetPdfObject().GetAsName(PdfName.Version));
1976-
if (catalogVersion.CompareTo(pdfVersion) > 0) {
1977-
pdfVersion = catalogVersion;
1978-
}
1979-
}
1980-
catch (ArgumentException) {
1981-
LogManager.GetLogger(typeof(iText.Kernel.Pdf.PdfDocument)).Error(iText.IO.LogMessageConstant.DOCUMENT_VERSION_IN_CATALOG_CORRUPTED
1982-
);
1983-
}
1984-
}
1961+
UpdatePdfVersionFromCatalog();
19851962
PdfStream xmpMetadataStream = catalog.GetPdfObject().GetAsStream(PdfName.Metadata);
19861963
if (xmpMetadataStream != null) {
19871964
xmpMetadata = xmpMetadataStream.GetBytes();
@@ -2492,6 +2469,45 @@ private String AddModifiedPostfix(String producer) {
24922469
}
24932470
}
24942471

2472+
private void UpdatePdfVersionFromCatalog() {
2473+
if (catalog.GetPdfObject().ContainsKey(PdfName.Version)) {
2474+
// The version of the PDF specification to which the document conforms (for example, 1.4)
2475+
// if later than the version specified in the file's header
2476+
try {
2477+
PdfVersion catalogVersion = PdfVersion.FromPdfName(catalog.GetPdfObject().GetAsName(PdfName.Version));
2478+
if (catalogVersion.CompareTo(pdfVersion) > 0) {
2479+
pdfVersion = catalogVersion;
2480+
}
2481+
}
2482+
catch (ArgumentException) {
2483+
ProcessReadingError(iText.IO.LogMessageConstant.DOCUMENT_VERSION_IN_CATALOG_CORRUPTED);
2484+
}
2485+
}
2486+
}
2487+
2488+
private void ReadDocumentIds() {
2489+
PdfArray id = reader.trailer.GetAsArray(PdfName.ID);
2490+
if (id != null) {
2491+
if (id.Size() == 2) {
2492+
originalDocumentId = id.GetAsString(0);
2493+
modifiedDocumentId = id.GetAsString(1);
2494+
}
2495+
if (originalDocumentId == null || modifiedDocumentId == null) {
2496+
ProcessReadingError(iText.IO.LogMessageConstant.DOCUMENT_IDS_ARE_CORRUPTED);
2497+
}
2498+
}
2499+
}
2500+
2501+
private void ProcessReadingError(String errorMessage) {
2502+
if (PdfReader.StrictnessLevel.CONSERVATIVE.IsStricter(reader.GetStrictnessLevel())) {
2503+
ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.PdfDocument));
2504+
logger.Error(errorMessage);
2505+
}
2506+
else {
2507+
throw new PdfException(errorMessage);
2508+
}
2509+
}
2510+
24952511
private static void OverrideFullCompressionInWriterProperties(WriterProperties properties, bool readerHasXrefStream
24962512
) {
24972513
if (true == properties.isFullCompression && !readerHasXrefStream) {

itext/itext.kernel/itext/kernel/pdf/PdfReader.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ source product.
5454
namespace iText.Kernel.Pdf {
5555
/// <summary>Reads a PDF document.</summary>
5656
public class PdfReader : IDisposable {
57+
/// <summary>
58+
/// The default
59+
/// <see cref="StrictnessLevel"/>
60+
/// to be used.
61+
/// </summary>
62+
public static readonly PdfReader.StrictnessLevel DEFAULT_STRICTNESS_LEVEL = PdfReader.StrictnessLevel.LENIENT;
63+
5764
private const String endstream1 = "endstream";
5865

5966
private const String endstream2 = "\nendstream";
@@ -72,6 +79,8 @@ public class PdfReader : IDisposable {
7279

7380
private bool memorySavingMode;
7481

82+
private PdfReader.StrictnessLevel strictnessLevel = DEFAULT_STRICTNESS_LEVEL;
83+
7584
//indicate nearest first Indirect reference object which includes current reading the object, using for PdfString decrypt
7685
private PdfIndirectReference currentIndirectReference;
7786

@@ -210,6 +219,49 @@ public virtual iText.Kernel.Pdf.PdfReader SetMemorySavingMode(bool memorySavingM
210219
return this;
211220
}
212221

222+
/// <summary>
223+
/// Get the current
224+
/// <see cref="StrictnessLevel"/>
225+
/// of the reader.
226+
/// </summary>
227+
/// <returns>
228+
/// the current
229+
/// <see cref="StrictnessLevel"/>
230+
/// </returns>
231+
public virtual PdfReader.StrictnessLevel GetStrictnessLevel() {
232+
return strictnessLevel;
233+
}
234+
235+
/// <summary>
236+
/// Set the
237+
/// <see cref="StrictnessLevel"/>
238+
/// for the reader.
239+
/// </summary>
240+
/// <remarks>
241+
/// Set the
242+
/// <see cref="StrictnessLevel"/>
243+
/// for the reader. If the argument is
244+
/// <see langword="null"/>
245+
/// , then
246+
/// the
247+
/// <see cref="DEFAULT_STRICTNESS_LEVEL"/>
248+
/// will be used.
249+
/// </remarks>
250+
/// <param name="strictnessLevel">
251+
/// the
252+
/// <see cref="StrictnessLevel"/>
253+
/// to set
254+
/// </param>
255+
/// <returns>
256+
/// this
257+
/// <see cref="PdfReader"/>
258+
/// instance
259+
/// </returns>
260+
public virtual iText.Kernel.Pdf.PdfReader SetStrictnessLevel(PdfReader.StrictnessLevel strictnessLevel) {
261+
this.strictnessLevel = strictnessLevel == null ? DEFAULT_STRICTNESS_LEVEL : strictnessLevel;
262+
return this;
263+
}
264+
213265
/// <summary>
214266
/// Gets whether
215267
/// <see cref="Close()"/>
@@ -1552,6 +1604,52 @@ public virtual void Close() {
15521604
}
15531605
}
15541606

1607+
/// <summary>Enumeration representing the strictness level for reading.</summary>
1608+
public sealed class StrictnessLevel {
1609+
/// <summary>
1610+
/// The reading strictness level at which iText fails (throws an exception) in case of
1611+
/// contradiction with PDF specification, but still recovers from mild parsing errors
1612+
/// and ambiguities.
1613+
/// </summary>
1614+
public static readonly PdfReader.StrictnessLevel CONSERVATIVE = new PdfReader.StrictnessLevel(5000);
1615+
1616+
/// <summary>
1617+
/// The reading strictness level at which iText tries to recover from parsing
1618+
/// errors if possible.
1619+
/// </summary>
1620+
public static readonly PdfReader.StrictnessLevel LENIENT = new PdfReader.StrictnessLevel(3000);
1621+
1622+
private readonly int levelValue;
1623+
1624+
internal StrictnessLevel(int levelValue) {
1625+
this.levelValue = levelValue;
1626+
}
1627+
1628+
/// <summary>
1629+
/// Checks whether the current instance represents more strict reading level than
1630+
/// the provided one.
1631+
/// </summary>
1632+
/// <remarks>
1633+
/// Checks whether the current instance represents more strict reading level than
1634+
/// the provided one. Note that the
1635+
/// <see langword="null"/>
1636+
/// is less strict than any other value.
1637+
/// </remarks>
1638+
/// <param name="compareWith">
1639+
/// the
1640+
/// <see cref="StrictnessLevel"/>
1641+
/// to compare with
1642+
/// </param>
1643+
/// <returns>
1644+
///
1645+
/// <see langword="true"/>
1646+
/// if the current level is stricter than the provided one
1647+
/// </returns>
1648+
public bool IsStricter(PdfReader.StrictnessLevel compareWith) {
1649+
return compareWith == null || this.levelValue > compareWith.levelValue;
1650+
}
1651+
}
1652+
15551653
void System.IDisposable.Dispose() {
15561654
Close();
15571655
}

port-hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
923408ccb8e69382d597778d71847b73717eae25
1+
076595cb2ad2ba96ebf3319ab6efb99b2ebbd2e0

0 commit comments

Comments
 (0)