Skip to content

Commit e0488e9

Browse files
author
Eugene Bochilo
committed
Support StructTreeRoot comparison, fix minor bugs
DEVSIX-8413
1 parent c367aa5 commit e0488e9

File tree

17 files changed

+640
-29
lines changed

17 files changed

+640
-29
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2024 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is offered under a commercial and under the AGPL license.
7+
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
8+
9+
AGPL licensing:
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU Affero General Public License as published by
12+
the Free Software Foundation, either version 3 of the License, or
13+
(at your option) any later version.
14+
15+
This program is distributed in the hope that it will be useful,
16+
but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
GNU Affero General Public License for more details.
19+
20+
You should have received a copy of the GNU Affero General Public License
21+
along with this program. If not, see <https://www.gnu.org/licenses/>.
22+
*/
23+
package com.itextpdf.commons.utils;
24+
25+
/**
26+
* Class which represents a pair of key and value.
27+
*
28+
* @param <K> key parameter type.
29+
* @param <V> value parameter type.
30+
*/
31+
public class Pair<K, V> {
32+
private final K key;
33+
private final V value;
34+
35+
/**
36+
* Creates key-value pair.
37+
*
38+
* @param key key parameter
39+
* @param value value parameter
40+
*/
41+
public Pair(K key, V value) {
42+
this.key = key;
43+
this.value = value;
44+
}
45+
46+
/**
47+
* Gets key parameter.
48+
*
49+
* @return key parameter.
50+
*/
51+
public K getKey() {
52+
return key;
53+
}
54+
55+
/**
56+
* Gets value parameter.
57+
*
58+
* @return value parameter.
59+
*/
60+
public V getValue() {
61+
return value;
62+
}
63+
}

io/src/main/java/com/itextpdf/io/source/PdfTokenizer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,9 @@ public long getNextEof() throws java.io.IOException {
259259
// 6 stands for '%%EOF' length + 1
260260
return currentPosition + eofPosition + 6;
261261
}
262-
} while (!str.isEmpty());
262+
// Change current position to ensure '%%EOF' is not cut in half.
263+
file.seek(file.getPosition() - 4);
264+
} while (str.length() > 4);
263265
throw new IOException(IoExceptionMessageConstant.PDF_EOF_NOT_FOUND, this);
264266
}
265267

io/src/test/java/com/itextpdf/io/source/PdfTokenizerTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,24 @@ public void getNextEofLongTextTest() throws IOException {
233233
}
234234
}
235235

236+
@Test
237+
public void getNextEofWhichIsCutTest() throws IOException {
238+
StringBuilder stringBuilder = new StringBuilder();
239+
// We append 'a' 124 times because buffer has 128 bytes length.
240+
// This way '%%EOF' is cut and first string only contains '%%EO'
241+
for (int i = 0; i < 124; ++i) {
242+
stringBuilder.append("a");
243+
}
244+
stringBuilder.append("%%EOF");
245+
246+
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
247+
try (PdfTokenizer tok = new PdfTokenizer(new RandomAccessFileOrArray(
248+
factory.createSource(stringBuilder.toString().getBytes(StandardCharsets.ISO_8859_1))))) {
249+
long eofPosition = tok.getNextEof();
250+
Assert.assertEquals(124 + 6, eofPosition);
251+
}
252+
}
253+
236254
@Test
237255
public void getNextEofSeveralEofTest() throws IOException {
238256
String data = "some text %%EOFto test \nget%%EOFting end of\n fil%%EOFe logic%%EOF";
@@ -245,6 +263,17 @@ public void getNextEofSeveralEofTest() throws IOException {
245263
}
246264
}
247265

266+
@Test
267+
public void getNextEofNoEofTest() throws IOException {
268+
String data = "some text to test \ngetting end of\n file logic";
269+
270+
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
271+
try (PdfTokenizer tok = new PdfTokenizer(new RandomAccessFileOrArray(
272+
factory.createSource(data.getBytes(StandardCharsets.ISO_8859_1))))) {
273+
Assert.assertThrows(com.itextpdf.io.exceptions.IOException.class, () -> tok.getNextEof());
274+
}
275+
}
276+
248277
@Test
249278
public void getDecodedStringContentTest() throws IOException {
250279
String data = "/Name1 15";

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfArray.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ This file is part of the iText (R) project.
2929

3030
import java.util.ArrayList;
3131
import java.util.Collection;
32+
import java.util.Collections;
3233
import java.util.Iterator;
3334
import java.util.List;
3435

@@ -325,6 +326,15 @@ public List<PdfObject> subList(int fromIndex, int toIndex) {
325326
return list.subList(fromIndex, toIndex);
326327
}
327328

329+
/**
330+
* Returns unmodifiable {@link List} representation of this PdfArray.
331+
*
332+
* @return unmodifiable {@link List} representation of this PdfArray
333+
*/
334+
public List<PdfObject> toList() {
335+
return Collections.unmodifiableList(list);
336+
}
337+
328338
@Override
329339
public byte getType() {
330340
return ARRAY;
@@ -351,7 +361,7 @@ public PdfObject get(int index, boolean asDirect) {
351361
return list.get(index);
352362
else {
353363
PdfObject obj = list.get(index);
354-
if (obj.getType() == INDIRECT_REFERENCE)
364+
if (obj != null && obj.getType() == INDIRECT_REFERENCE)
355365
return ((PdfIndirectReference) obj).getRefersTo(true);
356366
else
357367
return obj;

kernel/src/test/java/com/itextpdf/kernel/pdf/PdfRevisionsReaderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public void documentWithStreamAndTableXref() throws IOException {
199199

200200
DocumentRevision secondRevision = revisionsReader.getAllRevisions().get(1);
201201
assertResultingRevision(secondRevision, 1, 2, 3, 4, 5, 6, 7, 8);
202-
Assert.assertEquals(1550, secondRevision.getEofOffset());
202+
Assert.assertEquals(1381, secondRevision.getEofOffset());
203203

204204
DocumentRevision firstRevision = revisionsReader.getAllRevisions().get(2);
205205
assertResultingRevision(firstRevision);

0 commit comments

Comments
 (0)