Skip to content

Commit

Permalink
Merge branch 'develop' into devsecops
Browse files Browse the repository at this point in the history
  • Loading branch information
aleks-ivanov committed Mar 23, 2024
2 parents b66cd7d + e12f81e commit b5d25b9
Show file tree
Hide file tree
Showing 16 changed files with 468 additions and 2 deletions.
39 changes: 39 additions & 0 deletions itext.tests/itext.io.tests/itext/io/source/PdfTokenizerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System;
using System.Text;
using iText.Commons.Utils;
using iText.IO.Exceptions;
using iText.Test;
Expand Down Expand Up @@ -167,6 +168,44 @@ public virtual void ReadFullyThenReadStringTest() {
NUnit.Framework.Assert.AreEqual("15", tok.ReadString(data.Length));
}

[NUnit.Framework.Test]
public virtual void GetNextEofShortTextTest() {
String data = "some text to test \ngetting end of\n file logic%%EOF";
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
using (PdfTokenizer tok = new PdfTokenizer(new RandomAccessFileOrArray(factory.CreateSource(data.GetBytes(
iText.Commons.Utils.EncodingUtil.ISO_8859_1))))) {
long eofPosition = tok.GetNextEof();
NUnit.Framework.Assert.AreEqual(data.Length + 1, eofPosition);
}
}

[NUnit.Framework.Test]
public virtual void GetNextEofLongTextTest() {
String data = "some text to test \ngetting end of\n file logic";
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 20; ++i) {
stringBuilder.Append(data);
}
stringBuilder.Append("%%EOF");
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
using (PdfTokenizer tok = new PdfTokenizer(new RandomAccessFileOrArray(factory.CreateSource(stringBuilder.
ToString().GetBytes(iText.Commons.Utils.EncodingUtil.ISO_8859_1))))) {
long eofPosition = tok.GetNextEof();
NUnit.Framework.Assert.AreEqual(data.Length * 20 + 6, eofPosition);
}
}

[NUnit.Framework.Test]
public virtual void GetNextEofSeveralEofTest() {
String data = "some text %%EOFto test \nget%%EOFting end of\n fil%%EOFe logic%%EOF";
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
using (PdfTokenizer tok = new PdfTokenizer(new RandomAccessFileOrArray(factory.CreateSource(data.GetBytes(
iText.Commons.Utils.EncodingUtil.ISO_8859_1))))) {
long eofPosition = tok.GetNextEof();
NUnit.Framework.Assert.AreEqual(data.IndexOf("%%EOF", StringComparison.Ordinal) + 6, eofPosition);
}
}

[NUnit.Framework.Test]
public virtual void GetDecodedStringContentTest() {
String data = "/Name1 15";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2024 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using iText.Test;

namespace iText.Kernel.Pdf {
[NUnit.Framework.Category("UnitTest")]
public class PdfRevisionsReaderTest : ExtendedITextTest {
private static readonly String SOURCE_FOLDER = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
.CurrentContext.TestDirectory) + "/resources/itext/kernel/pdf/PdfRevisionsReaderTest/";

[NUnit.Framework.Test]
public virtual void SingleRevisionDocumentTest() {
String filename = SOURCE_FOLDER + "singleRevisionDocument.pdf";
using (PdfReader reader = new PdfReader(filename)) {
PdfRevisionsReader revisionsReader = new PdfRevisionsReader(reader);
IList<DocumentRevision> documentRevisions = revisionsReader.GetAllRevisions();
NUnit.Framework.Assert.AreEqual(1, documentRevisions.Count);
DocumentRevision firstRevision = documentRevisions[0];
AssertResultingRevision(firstRevision, 1, 2, 3, 4, 5, 6);
NUnit.Framework.Assert.AreEqual(929, firstRevision.GetEofOffset());
}
}

[NUnit.Framework.Test]
public virtual void SingleRevisionWithXrefStreamTest() {
String filename = SOURCE_FOLDER + "singleRevisionWithXrefStream.pdf";
using (PdfReader reader = new PdfReader(filename)) {
PdfRevisionsReader revisionsReader = new PdfRevisionsReader(reader);
IList<DocumentRevision> documentRevisions = revisionsReader.GetAllRevisions();
NUnit.Framework.Assert.AreEqual(1, documentRevisions.Count);
DocumentRevision firstRevision = documentRevisions[0];
AssertResultingRevision(firstRevision, 1, 2, 3, 4, 5, 6, 7, 8);
NUnit.Framework.Assert.AreEqual(1085, firstRevision.GetEofOffset());
}
}

[NUnit.Framework.Test]
public virtual void MultipleRevisionsDocument() {
String filename = SOURCE_FOLDER + "multipleRevisionsDocument.pdf";
using (PdfReader reader = new PdfReader(filename)) {
PdfRevisionsReader revisionsReader = new PdfRevisionsReader(reader);
IList<DocumentRevision> documentRevisions = revisionsReader.GetAllRevisions();
NUnit.Framework.Assert.AreEqual(3, documentRevisions.Count);
DocumentRevision firstRevision = documentRevisions[0];
AssertResultingRevision(firstRevision, 1, 2, 3, 4, 5, 6);
NUnit.Framework.Assert.AreEqual(929, firstRevision.GetEofOffset());
DocumentRevision secondRevision = documentRevisions[1];
AssertResultingRevision(secondRevision, 1, 3, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15);
NUnit.Framework.Assert.AreEqual(28119, secondRevision.GetEofOffset());
DocumentRevision thirdRevision = documentRevisions[2];
AssertResultingRevision(thirdRevision, 1, 3, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28);
NUnit.Framework.Assert.AreEqual(36207, thirdRevision.GetEofOffset());
}
}

[NUnit.Framework.Test]
public virtual void FreeReferencesDocument() {
String filename = SOURCE_FOLDER + "freeReferencesDocument.pdf";
using (PdfReader reader = new PdfReader(filename)) {
PdfRevisionsReader revisionsReader = new PdfRevisionsReader(reader);
IList<DocumentRevision> documentRevisions = revisionsReader.GetAllRevisions();
NUnit.Framework.Assert.AreEqual(5, documentRevisions.Count);
DocumentRevision firstRevision = documentRevisions[0];
AssertResultingRevision(firstRevision, 1, 2, 3, 4, 5, 6);
NUnit.Framework.Assert.AreEqual(929, firstRevision.GetEofOffset());
DocumentRevision secondRevision = documentRevisions[1];
AssertResultingRevision(secondRevision, 1, 3, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15);
NUnit.Framework.Assert.AreEqual(28119, secondRevision.GetEofOffset());
DocumentRevision thirdRevision = documentRevisions[2];
AssertResultingRevision(thirdRevision, 1, 3, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28);
NUnit.Framework.Assert.AreEqual(36207, thirdRevision.GetEofOffset());
DocumentRevision fourthRevision = documentRevisions[3];
AssertResultingRevision(fourthRevision, new int[] { 1, 3, 23, 24 }, new int[] { 0, 0, 1, 1 });
NUnit.Framework.Assert.AreEqual(37006, fourthRevision.GetEofOffset());
DocumentRevision fifthRevision = documentRevisions[4];
AssertResultingRevision(fifthRevision, new int[] { 1, 3, 19, 20, 21, 22, 23, 25 }, new int[] { 0, 0, 1, 1,
1, 1, 1, 1 });
NUnit.Framework.Assert.AreEqual(38094, fifthRevision.GetEofOffset());
}
}

[NUnit.Framework.Test]
public virtual void MultipleRevisionsWithXrefStreamTest() {
String filename = SOURCE_FOLDER + "multipleRevisionsWithXrefStream.pdf";
using (PdfReader reader = new PdfReader(filename)) {
PdfRevisionsReader revisionsReader = new PdfRevisionsReader(reader);
IList<DocumentRevision> documentRevisions = revisionsReader.GetAllRevisions();
NUnit.Framework.Assert.AreEqual(3, documentRevisions.Count);
DocumentRevision firstRevision = documentRevisions[0];
AssertResultingRevision(firstRevision, 1, 2, 3, 4, 5, 6, 7, 8);
NUnit.Framework.Assert.AreEqual(1085, firstRevision.GetEofOffset());
DocumentRevision secondRevision = documentRevisions[1];
AssertResultingRevision(secondRevision, 1, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
NUnit.Framework.Assert.AreEqual(28137, secondRevision.GetEofOffset());
DocumentRevision thirdRevision = documentRevisions[2];
AssertResultingRevision(thirdRevision, 1, 3, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34);
NUnit.Framework.Assert.AreEqual(36059, thirdRevision.GetEofOffset());
}
}

[NUnit.Framework.Test]
public virtual void FreeReferencesWithXrefStream() {
String filename = SOURCE_FOLDER + "freeReferencesWithXrefStream.pdf";
using (PdfReader reader = new PdfReader(filename)) {
PdfRevisionsReader revisionsReader = new PdfRevisionsReader(reader);
IList<DocumentRevision> documentRevisions = revisionsReader.GetAllRevisions();
NUnit.Framework.Assert.AreEqual(5, documentRevisions.Count);
DocumentRevision firstRevision = documentRevisions[0];
AssertResultingRevision(firstRevision, 1, 2, 3, 4, 5, 6, 7, 8);
NUnit.Framework.Assert.AreEqual(1085, firstRevision.GetEofOffset());
DocumentRevision secondRevision = documentRevisions[1];
AssertResultingRevision(secondRevision, 1, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
NUnit.Framework.Assert.AreEqual(28137, secondRevision.GetEofOffset());
DocumentRevision thirdRevision = documentRevisions[2];
AssertResultingRevision(thirdRevision, 1, 3, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34);
NUnit.Framework.Assert.AreEqual(36059, thirdRevision.GetEofOffset());
DocumentRevision fourthRevision = documentRevisions[3];
AssertResultingRevision(fourthRevision, new int[] { 1, 3, 27, 28, 35 }, new int[] { 0, 0, 1, 1, 0 });
NUnit.Framework.Assert.AreEqual(36975, fourthRevision.GetEofOffset());
DocumentRevision fifthRevision = documentRevisions[4];
AssertResultingRevision(fifthRevision, new int[] { 1, 3, 23, 24, 25, 26, 27, 29, 36 }, new int[] { 0, 0, 1
, 1, 1, 1, 1, 1, 0 });
NUnit.Framework.Assert.AreEqual(38111, fifthRevision.GetEofOffset());
}
}

[NUnit.Framework.Test]
public virtual void DocumentWithStreamAndTableXref() {
String filename = SOURCE_FOLDER + "documentWithStreamAndTableXref.pdf";
using (PdfReader reader = new PdfReader(filename)) {
PdfRevisionsReader revisionsReader = new PdfRevisionsReader(reader);
IList<DocumentRevision> documentRevisions = revisionsReader.GetAllRevisions();
NUnit.Framework.Assert.AreEqual(3, documentRevisions.Count);
DocumentRevision thirdRevision = revisionsReader.GetAllRevisions()[0];
// xref was broken in this revision and fixed in the next one
AssertResultingRevision(thirdRevision, new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, new int[] { 0, 0, 0, 0, 0,
0, 65535, 0, 0 });
NUnit.Framework.Assert.AreEqual(1381, thirdRevision.GetEofOffset());
DocumentRevision secondRevision = revisionsReader.GetAllRevisions()[1];
AssertResultingRevision(secondRevision, 1, 2, 3, 4, 5, 6, 7, 8);
NUnit.Framework.Assert.AreEqual(1550, secondRevision.GetEofOffset());
DocumentRevision firstRevision = revisionsReader.GetAllRevisions()[2];
AssertResultingRevision(firstRevision);
NUnit.Framework.Assert.AreEqual(1550, firstRevision.GetEofOffset());
}
}

private void AssertResultingRevision(DocumentRevision documentRevision, params int[] objNumbers) {
AssertResultingRevision(documentRevision, objNumbers, new int[objNumbers.Length]);
}

private void AssertResultingRevision(DocumentRevision documentRevision, int[] objNumbers, int[] objGens) {
NUnit.Framework.Assert.AreEqual(objNumbers.Length, objGens.Length);
NUnit.Framework.Assert.AreEqual(objNumbers.Length + 1, documentRevision.GetModifiedObjects().Count);
for (int i = 0; i < objNumbers.Length; ++i) {
int objNumber = objNumbers[i];
int objGen = objGens[i];
NUnit.Framework.Assert.IsTrue(documentRevision.GetModifiedObjects().Any((reference) => reference.GetObjNumber
() == objNumber && reference.GetGenNumber() == objGen));
}
NUnit.Framework.Assert.IsTrue(documentRevision.GetModifiedObjects().Any((reference) => reference.GetObjNumber
() == 0 && reference.GetGenNumber() == 65535 && reference.IsFree()));
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ public sealed class IoExceptionMessageConstant {

public const String PDF_STARTXREF_NOT_FOUND = "PDF startxref not found.";

public const String PDF_EOF_NOT_FOUND = "PDF \"%%EOF\" marker is not found.";

public const String PHOTOMETRIC_IS_NOT_SUPPORTED = "Photometric {0} is not supported.";

public const String PLANAR_IMAGES_ARE_NOT_SUPPORTED = "Planar images are not supported.";
Expand Down
18 changes: 18 additions & 0 deletions itext/itext.io/itext/io/source/PdfTokenizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,24 @@ public virtual long GetStartxref() {
throw new iText.IO.Exceptions.IOException(IoExceptionMessageConstant.PDF_STARTXREF_NOT_FOUND, this);
}

/// <summary>Gets next %%EOF marker in current PDF file.</summary>
/// <returns>next %%EOF marker position</returns>
public virtual long GetNextEof() {
int arrLength = 128;
String str;
do {
long currentPosition = file.GetPosition();
str = ReadString(arrLength);
long eofPosition = str.IndexOf("%%EOF", StringComparison.Ordinal);
if (eofPosition >= 0) {
// 6 stands for '%%EOF' length + 1
return currentPosition + eofPosition + 6;
}
}
while (!String.IsNullOrEmpty(str));
throw new iText.IO.Exceptions.IOException(IoExceptionMessageConstant.PDF_EOF_NOT_FOUND, this);
}

public virtual void NextValidToken() {
int level = 0;
byte[] n1 = null;
Expand Down
69 changes: 69 additions & 0 deletions itext/itext.kernel/itext/kernel/pdf/DocumentRevision.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2024 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;

namespace iText.Kernel.Pdf {
/// <summary>Class which stores information about single PDF document revision.</summary>
public class DocumentRevision {
private readonly long eofOffset;

private readonly ICollection<PdfIndirectReference> modifiedObjects;

/// <summary>
/// Creates
/// <see cref="DocumentRevision"/>
/// from end-of-file byte position and a set of indirect references which were
/// modified in this document revision.
/// </summary>
/// <param name="eofOffset">end-of-file byte position</param>
/// <param name="modifiedObjects">
///
/// <see cref="Java.Util.Set{E}"/>
/// of
/// <see cref="PdfIndirectReference"/>
/// objects which were modified
/// </param>
public DocumentRevision(long eofOffset, ICollection<PdfIndirectReference> modifiedObjects) {
this.eofOffset = eofOffset;
this.modifiedObjects = modifiedObjects;
}

/// <summary>Gets end-of-file byte position.</summary>
/// <returns>end-of-file byte position</returns>
public virtual long GetEofOffset() {
return eofOffset;
}

/// <summary>Gets objects which were modified in this document revision.</summary>
/// <returns>
///
/// <see cref="Java.Util.Set{E}"/>
/// of
/// <see cref="PdfIndirectReference"/>
/// objects which were modified
/// </returns>
public virtual ICollection<PdfIndirectReference> GetModifiedObjects() {
return modifiedObjects;
}
}
}
Loading

0 comments on commit b5d25b9

Please sign in to comment.