Skip to content

Commit 4ac8b8c

Browse files
yulian-gaponenkoitext-teamcity
authored andcommitted
Merge branch 'hotfix/xref_free_refs' into develop
Autoported commit. Original commit hash: [ccaa2185d]
2 parents f895ac3 + 956d308 commit 4ac8b8c

File tree

16 files changed

+352
-52
lines changed

16 files changed

+352
-52
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using iText.Test;
5+
6+
namespace iText.Kernel.Pdf {
7+
public class FreeReferencesTest : ExtendedITextTest {
8+
public static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
9+
+ "/test/itext/kernel/pdf/FreeReferencesTest/";
10+
11+
public static readonly String sourceFolder = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
12+
.CurrentContext.TestDirectory) + "/resources/itext/kernel/pdf/FreeReferencesTest/";
13+
14+
[NUnit.Framework.OneTimeSetUp]
15+
public static void BeforeClass() {
16+
CreateOrClearDestinationFolder(destinationFolder);
17+
}
18+
19+
/// <exception cref="System.IO.IOException"/>
20+
[NUnit.Framework.Test]
21+
public virtual void FreeReferencesTest01() {
22+
String src = "freeRefsGapsAndMaxGen.pdf";
23+
String @out = "freeReferencesTest01.pdf";
24+
PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + src), new PdfWriter(destinationFolder
25+
+ @out));
26+
pdfDocument.Close();
27+
String[] xrefString = ExtractXrefTableAsStrings(@out);
28+
String[] expected = new String[] { "xref\n" + "0 15\n" + "0000000004 65535 f \n" + "0000000269 00000 n \n"
29+
+ "0000000561 00000 n \n" + "0000000314 00000 n \n" + "0000000005 65535 f \n" + "0000000006 00000 f \n"
30+
+ "0000000007 00000 f \n" + "0000000008 00000 f \n" + "0000000009 00000 f \n" + "0000000010 00000 f \n"
31+
+ "0000000011 00000 f \n" + "0000000000 00001 f \n" + "0000000133 00000 n \n" + "0000000015 00000 n \n"
32+
+ "0000000613 00000 n \n" };
33+
NUnit.Framework.Assert.AreEqual(expected, xrefString);
34+
}
35+
36+
/// <exception cref="System.IO.IOException"/>
37+
[NUnit.Framework.Test]
38+
public virtual void FreeReferencesTest02() {
39+
String src = "freeRefsGapsAndMaxGen.pdf";
40+
String @out = "freeReferencesTest02.pdf";
41+
PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + src), new PdfWriter(destinationFolder
42+
+ @out), new StampingProperties().UseAppendMode());
43+
pdfDocument.Close();
44+
String[] xrefString = ExtractXrefTableAsStrings(@out);
45+
String[] expected = new String[] { "xref\n" + "0 5\n" + "0000000010 65535 f \n" + "0000000269 00000 n \n"
46+
+ "0000000569 00000 n \n" + "0000000314 00000 n \n" + "0000000000 65535 f \n" + "10 5\n" + "0000000011 00000 f \n"
47+
+ "0000000000 00001 f \n" + "0000000133 00000 n \n" + "0000000015 00000 n \n" + "0000000480 00000 n \n"
48+
, "xref\n" + "0 1\n" + "0000000004 65535 f \n" + "3 9\n" + "0000000995 00000 n \n" + "0000000005 65535 f \n"
49+
+ "0000000006 00000 f \n" + "0000000007 00000 f \n" + "0000000008 00000 f \n" + "0000000009 00000 f \n"
50+
+ "0000000010 00000 f \n" + "0000000011 00000 f \n" + "0000000000 00001 f \n" };
51+
// Append mode, no possibility to fix subsections in first xref
52+
NUnit.Framework.Assert.AreEqual(expected, xrefString);
53+
}
54+
55+
/// <exception cref="System.IO.IOException"/>
56+
[NUnit.Framework.Test]
57+
public virtual void FreeReferencesTest03() {
58+
String src = "freeRefsDeletedObj.pdf";
59+
String @out = "freeReferencesTest03.pdf";
60+
PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + src), new PdfWriter(destinationFolder
61+
+ @out), new StampingProperties().UseAppendMode());
62+
pdfDocument.AddNewPage();
63+
pdfDocument.Close();
64+
String[] xrefString = ExtractXrefTableAsStrings(@out);
65+
String[] expected = new String[] { "xref\n" + "0 7\n" + "0000000000 65535 f \n" + "0000000265 00000 n \n"
66+
+ "0000000564 00000 n \n" + "0000000310 00000 n \n" + "0000000132 00000 n \n" + "0000000015 00001 n \n"
67+
+ "0000000476 00000 n \n", "xref\n" + "0 1\n" + "0000000005 65535 n \n" + "3 3\n" + "0000000923 00000 n \n"
68+
+ "0000001170 00000 n \n" + "0000000000 00002 f \n" + "7 1\n" + "0000001303 00000 n \n", "xref\n" + "0 4\n"
69+
+ "0000000005 65535 f \n" + "0000001706 00000 n \n" + "0000001998 00000 n \n" + "0000001751 00000 n \n"
70+
+ "5 1\n" + "0000000000 00002 f \n" + "8 2\n" + "0000002055 00000 n \n" + "0000002156 00000 n \n" };
71+
NUnit.Framework.Assert.AreEqual(expected, xrefString);
72+
}
73+
74+
/// <exception cref="System.IO.IOException"/>
75+
[NUnit.Framework.Test]
76+
public virtual void FreeReferencesTest04() {
77+
String src = "simpleDoc.pdf";
78+
String @out = "freeReferencesTest04.pdf";
79+
PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + src), new PdfWriter(destinationFolder
80+
+ @out));
81+
PdfObject contentsObj = pdfDocument.GetPage(1).GetPdfObject().Remove(PdfName.Contents);
82+
NUnit.Framework.Assert.IsTrue(contentsObj is PdfIndirectReference);
83+
PdfIndirectReference contentsRef = (PdfIndirectReference)contentsObj;
84+
contentsRef.SetFree();
85+
PdfObject freedContentsRefRefersTo = contentsRef.GetRefersTo();
86+
NUnit.Framework.Assert.IsNull(freedContentsRefRefersTo);
87+
pdfDocument.Close();
88+
String[] xrefString = ExtractXrefTableAsStrings(@out);
89+
String[] expected = new String[] { "xref\n" + "0 7\n" + "0000000005 65535 f \n" + "0000000133 00000 n \n"
90+
+ "0000000425 00000 n \n" + "0000000178 00000 n \n" + "0000000015 00000 n \n" + "0000000000 00001 f \n"
91+
+ "0000000476 00000 n \n" };
92+
NUnit.Framework.Assert.AreEqual(expected, xrefString);
93+
}
94+
95+
/// <exception cref="System.IO.IOException"/>
96+
[NUnit.Framework.Test]
97+
public virtual void FreeReferencesTest05() {
98+
String src = "simpleDocWithSubsections.pdf";
99+
String @out = "freeReferencesTest05.pdf";
100+
PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + src), new PdfWriter(destinationFolder
101+
+ @out));
102+
pdfDocument.Close();
103+
String[] xrefString = ExtractXrefTableAsStrings(@out);
104+
String[] expected = new String[] { "xref\n" + "0 14\n" + "0000000004 65535 f \n" + "0000000269 00000 n \n"
105+
+ "0000000561 00000 n \n" + "0000000314 00000 n \n" + "0000000005 00000 f \n" + "0000000006 00000 f \n"
106+
+ "0000000007 00000 f \n" + "0000000008 00000 f \n" + "0000000009 00000 f \n" + "0000000010 00000 f \n"
107+
+ "0000000000 00000 f \n" + "0000000133 00000 n \n" + "0000000015 00000 n \n" + "0000000613 00000 n \n"
108+
};
109+
NUnit.Framework.Assert.AreEqual(expected, xrefString);
110+
}
111+
112+
/// <exception cref="System.IO.IOException"/>
113+
[NUnit.Framework.Test]
114+
public virtual void FreeReferencesTest06() {
115+
String src = "simpleDocWithSubsections.pdf";
116+
String @out = "freeReferencesTest06.pdf";
117+
PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + src), new PdfWriter(destinationFolder
118+
+ @out), new StampingProperties().UseAppendMode());
119+
pdfDocument.Close();
120+
String[] xrefString = ExtractXrefTableAsStrings(@out);
121+
String[] expected = new String[] { "xref\n" + "0 4\n" + "0000000000 65535 f \n" + "0000000269 00000 n \n"
122+
+ "0000000569 00000 n \n" + "0000000314 00000 n \n" + "11 3\n" + "0000000133 00000 n \n" + "0000000015 00000 n \n"
123+
+ "0000000480 00000 n \n", "xref\n" + "0 1\n" + "0000000004 65535 f \n" + "3 8\n" + "0000000935 00000 n \n"
124+
+ "0000000005 00000 f \n" + "0000000006 00000 f \n" + "0000000007 00000 f \n" + "0000000008 00000 f \n"
125+
+ "0000000009 00000 f \n" + "0000000010 00000 f \n" + "0000000000 00000 f \n" };
126+
// Append mode, no possibility to fix subsections in first xref
127+
NUnit.Framework.Assert.AreEqual(expected, xrefString);
128+
}
129+
130+
/// <exception cref="System.IO.IOException"/>
131+
[NUnit.Framework.Test]
132+
public virtual void FreeReferencesTest07() {
133+
String @out = "freeReferencesTest07.pdf";
134+
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + @out));
135+
pdfDocument.CreateNextIndirectReference();
136+
pdfDocument.AddNewPage();
137+
pdfDocument.Close();
138+
String[] xrefString = ExtractXrefTableAsStrings(@out);
139+
String[] expected = new String[] { "xref\n" + "0 7\n" + "0000000004 65535 f \n" + "0000000203 00000 n \n"
140+
+ "0000000414 00000 n \n" + "0000000248 00000 n \n" + "0000000000 00001 f \n" + "0000000088 00000 n \n"
141+
+ "0000000015 00000 n \n" };
142+
NUnit.Framework.Assert.AreEqual(expected, xrefString);
143+
}
144+
145+
/// <exception cref="System.IO.IOException"/>
146+
[NUnit.Framework.Test]
147+
public virtual void FreeReferencesTest08() {
148+
String src = "simpleDoc.pdf";
149+
String @out = "freeReferencesTest08.pdf";
150+
PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + src), new PdfWriter(destinationFolder
151+
+ @out), new StampingProperties().UseAppendMode());
152+
PdfObject contentsObj = pdfDocument.GetPage(1).GetPdfObject().Remove(PdfName.Contents);
153+
pdfDocument.GetPage(1).SetModified();
154+
NUnit.Framework.Assert.IsTrue(contentsObj is PdfIndirectReference);
155+
PdfIndirectReference contentsRef = (PdfIndirectReference)contentsObj;
156+
contentsRef.SetFree();
157+
PdfObject freedContentsRefRefersTo = contentsRef.GetRefersTo();
158+
NUnit.Framework.Assert.IsNull(freedContentsRefRefersTo);
159+
pdfDocument.Close();
160+
String[] xrefString = ExtractXrefTableAsStrings(@out);
161+
String[] expected = new String[] { "xref\n" + "0 7\n" + "0000000000 65535 f \n" + "0000000265 00000 n \n"
162+
+ "0000000564 00000 n \n" + "0000000310 00000 n \n" + "0000000132 00000 n \n" + "0000000015 00000 n \n"
163+
+ "0000000476 00000 n \n", "xref\n" + "0 1\n" + "0000000005 65535 f \n" + "3 3\n" + "0000000923 00000 n \n"
164+
+ "0000001170 00000 n \n" + "0000000000 00001 f \n" };
165+
NUnit.Framework.Assert.AreEqual(expected, xrefString);
166+
}
167+
168+
/// <exception cref="System.IO.IOException"/>
169+
private String[] ExtractXrefTableAsStrings(String @out) {
170+
byte[] outPdfBytes = ReadFile(destinationFolder + @out);
171+
String outPdfContent = iText.IO.Util.JavaUtil.GetStringForBytes(outPdfBytes, Encoding.ASCII);
172+
String xrefStr = "\nxref";
173+
String trailerStr = "trailer";
174+
int xrefInd = outPdfContent.IndexOf(xrefStr, StringComparison.Ordinal);
175+
int trailerInd = outPdfContent.IndexOf(trailerStr, StringComparison.Ordinal);
176+
int lastXrefInd = outPdfContent.LastIndexOf(xrefStr);
177+
IList<String> xrefs = new List<String>();
178+
while (true) {
179+
xrefs.Add(outPdfContent.JSubstring(xrefInd + 1, trailerInd));
180+
if (xrefInd == lastXrefInd) {
181+
break;
182+
}
183+
xrefInd = outPdfContent.IndexOf(xrefStr, xrefInd + 1);
184+
trailerInd = outPdfContent.IndexOf(trailerStr, trailerInd + 1);
185+
}
186+
return xrefs.ToArray(new String[xrefs.Count]);
187+
}
188+
}
189+
}

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ source product.
4242
*/
4343
using System;
4444
using System.IO;
45+
using System.Text;
4546
using iText.IO.Image;
4647
using iText.IO.Source;
4748
using iText.Kernel.Pdf.Navigation;
@@ -273,6 +274,31 @@ public virtual void TestFreeReference() {
273274
sourceFolder + "cmp_freeReference.pdf", destinationFolder, "diff_"));
274275
}
275276

277+
/// <exception cref="System.IO.IOException"/>
278+
/// <exception cref="System.Exception"/>
279+
[NUnit.Framework.Test]
280+
public virtual void FullCompressionAppendMode() {
281+
PdfWriter writer = new PdfWriter(destinationFolder + "fullCompressionAppendMode.pdf", new WriterProperties
282+
().SetFullCompressionMode(true).SetCompressionLevel(CompressionConstants.NO_COMPRESSION));
283+
PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "fullCompressionDoc.pdf"), writer,
284+
new StampingProperties().UseAppendMode());
285+
PdfPage page = pdfDocument.GetPage(1);
286+
PdfStream contentStream = new PdfStream();
287+
String contentStr = iText.IO.Util.JavaUtil.GetStringForBytes(pdfDocument.GetPage(1).GetFirstContentStream(
288+
).GetBytes(), Encoding.ASCII);
289+
contentStream.SetData(contentStr.Replace("/F1 16", "/F1 24").GetBytes(Encoding.ASCII));
290+
page.GetPdfObject().Put(PdfName.Contents, contentStream);
291+
page.SetModified();
292+
pdfDocument.Close();
293+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(destinationFolder + "fullCompressionAppendMode.pdf"
294+
, sourceFolder + "cmp_fullCompressionAppendMode.pdf", destinationFolder, "diff_"));
295+
PdfDocument assertDoc = new PdfDocument(new PdfReader(destinationFolder + "fullCompressionAppendMode.pdf")
296+
);
297+
NUnit.Framework.Assert.IsTrue(assertDoc.GetPdfObject(9).IsStream());
298+
NUnit.Framework.Assert.AreEqual(1, ((PdfDictionary)assertDoc.GetPdfObject(9)).GetAsNumber(PdfName.N).IntValue
299+
());
300+
}
301+
276302
/// <exception cref="System.IO.IOException"/>
277303
/// <exception cref="System.Exception"/>
278304
[NUnit.Framework.Test]

itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfPagesTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public virtual void RandomObjectPagesTest() {
162162
PdfPage testPage = document.RemovePage(1000);
163163
NUnit.Framework.Assert.IsTrue(testPage.GetPdfObject().GetIndirectReference() == null);
164164
document.AddPage(1000, testPage);
165-
NUnit.Framework.Assert.IsTrue(testPage.GetPdfObject().GetIndirectReference().GetObjNumber() < xrefSize);
165+
NUnit.Framework.Assert.IsTrue(testPage.GetPdfObject().GetIndirectReference().GetObjNumber() == xrefSize);
166166
for (int i = 0; i < pages.Length; i++) {
167167
NUnit.Framework.Assert.AreEqual(true, document.RemovePage(pages[i]), "Remove page");
168168
document.AddPage(i + 1, pages[i]);

itext.tests/itext.kernel.tests/itext/kernel/pdf/PdfReaderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ public virtual void PagesTest01() {
315315
PdfPage testPage = document.RemovePage(1000);
316316
NUnit.Framework.Assert.IsTrue(testPage.GetPdfObject().GetIndirectReference() == null);
317317
document.AddPage(1000, testPage);
318-
NUnit.Framework.Assert.IsTrue(testPage.GetPdfObject().GetIndirectReference().GetObjNumber() < xrefSize);
318+
NUnit.Framework.Assert.IsTrue(testPage.GetPdfObject().GetIndirectReference().GetObjNumber() == xrefSize);
319319
for (int i = 1; i < document.GetNumberOfPages() + 1; i++) {
320320
PdfPage page = document.GetPage(i);
321321
String content = iText.IO.Util.JavaUtil.GetStringForBytes(page.GetContentStream(0).GetBytes());
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* To change this license header, choose License Headers in Project Properties.
3+
* To change this template file, choose Tools | Templates
4+
* and open the template in the editor.
5+
*/
6+
using System;
7+
using iText.Test;
8+
9+
namespace iText.Kernel.Pdf {
10+
/// <author>benoit</author>
11+
public class PdfXrefTableTest : ExtendedITextTest {
12+
public static readonly String sourceFolder = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
13+
.CurrentContext.TestDirectory) + "/resources/itext/kernel/pdf/PdfXrefTableTest/";
14+
15+
public static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
16+
+ "/test/itext/kernel/pdf/PdfXrefTableTest/";
17+
18+
[NUnit.Framework.OneTimeSetUp]
19+
public static void BeforeClass() {
20+
CreateOrClearDestinationFolder(destinationFolder);
21+
}
22+
23+
/// <exception cref="System.IO.IOException"/>
24+
[NUnit.Framework.Test]
25+
public virtual void TestCreateAndUpdateXMP() {
26+
String created = destinationFolder + "testCreateAndUpdateXMP_create.pdf";
27+
String updated = destinationFolder + "testCreateAndUpdateXMP_update.pdf";
28+
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(created));
29+
pdfDocument.AddNewPage();
30+
pdfDocument.GetXmpMetadata(true);
31+
// create XMP metadata
32+
pdfDocument.Close();
33+
pdfDocument = new PdfDocument(new PdfReader(created), new PdfWriter(updated));
34+
PdfXrefTable xref = pdfDocument.GetXref();
35+
PdfIndirectReference ref0 = xref.Get(0);
36+
PdfIndirectReference freeRef = xref.Get(6);
37+
pdfDocument.Close();
38+
/*
39+
Current xref structure:
40+
xref
41+
0 8
42+
0000000006 65535 f % this is object 0; 6 refers to free object 6
43+
0000000203 00000 n
44+
0000000510 00000 n
45+
0000000263 00000 n
46+
0000000088 00000 n
47+
0000000015 00000 n
48+
0000000000 00001 f % this is object 6; 0 refers to free object 0; note generation number
49+
0000000561 00000 n
50+
*/
51+
NUnit.Framework.Assert.IsTrue(freeRef.IsFree());
52+
NUnit.Framework.Assert.AreEqual(ref0.offsetOrIndex, freeRef.objNr);
53+
NUnit.Framework.Assert.AreEqual(1, freeRef.genNr);
54+
}
55+
56+
/// <exception cref="System.IO.IOException"/>
57+
[NUnit.Framework.Test]
58+
public virtual void TestCreateAndUpdateTwiceXMP() {
59+
String created = destinationFolder + "testCreateAndUpdateTwiceXMP_create.pdf";
60+
String updated = destinationFolder + "testCreateAndUpdateTwiceXMP_update.pdf";
61+
String updatedAgain = destinationFolder + "testCreateAndUpdateTwiceXMP_updatedAgain.pdf";
62+
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(created));
63+
pdfDocument.AddNewPage();
64+
pdfDocument.GetXmpMetadata(true);
65+
// create XMP metadata
66+
pdfDocument.Close();
67+
pdfDocument = new PdfDocument(new PdfReader(created), new PdfWriter(updated));
68+
pdfDocument.Close();
69+
pdfDocument = new PdfDocument(new PdfReader(updated), new PdfWriter(updatedAgain));
70+
PdfXrefTable xref = pdfDocument.GetXref();
71+
PdfIndirectReference ref0 = xref.Get(0);
72+
PdfIndirectReference freeRef1 = xref.Get(6);
73+
PdfIndirectReference freeRef2 = xref.Get(7);
74+
pdfDocument.Close();
75+
/*
76+
Current xref structure:
77+
xref
78+
0 9
79+
0000000006 65535 f % this is object 0; 6 refers to free object 6
80+
0000000203 00000 n
81+
0000000510 00000 n
82+
0000000263 00000 n
83+
0000000088 00000 n
84+
0000000015 00000 n
85+
0000000007 00001 f % this is object 6; 7 refers to free object 7; note generation number
86+
0000000000 00001 f % this is object 7; 0 refers to free object 0; note generation number
87+
0000000561 00000 n
88+
*/
89+
NUnit.Framework.Assert.IsTrue(freeRef1.IsFree());
90+
NUnit.Framework.Assert.AreEqual(ref0.offsetOrIndex, freeRef1.objNr);
91+
NUnit.Framework.Assert.AreEqual(1, freeRef1.genNr);
92+
NUnit.Framework.Assert.IsTrue(freeRef2.IsFree());
93+
NUnit.Framework.Assert.AreEqual(freeRef1.offsetOrIndex, freeRef2.objNr);
94+
NUnit.Framework.Assert.AreEqual(1, freeRef2.genNr);
95+
pdfDocument.Close();
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)