Skip to content

Commit b569f71

Browse files
committed
Use PdfCatalog#getOutlines methods instead of PdfAChecker implementation to prevent SO exception during reading complex outline structure
DEVSIX-1822
1 parent 7d722c5 commit b569f71

File tree

3 files changed

+20
-27
lines changed

3 files changed

+20
-27
lines changed

pdfa/src/main/java/com/itextpdf/pdfa/checker/PdfAChecker.java

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,16 @@ This file is part of the iText (R) project.
3434
import com.itextpdf.kernel.pdf.PdfName;
3535
import com.itextpdf.kernel.pdf.PdfNumber;
3636
import com.itextpdf.kernel.pdf.PdfObject;
37+
import com.itextpdf.kernel.pdf.PdfOutline;
3738
import com.itextpdf.kernel.pdf.PdfPage;
3839
import com.itextpdf.kernel.pdf.PdfStream;
3940
import com.itextpdf.kernel.pdf.PdfString;
4041
import com.itextpdf.kernel.pdf.PdfXrefTable;
4142
import com.itextpdf.kernel.pdf.canvas.CanvasGraphicsState;
4243
import com.itextpdf.kernel.pdf.colorspace.PdfColorSpace;
4344

44-
import java.util.ArrayList;
4545
import java.util.HashMap;
4646
import java.util.HashSet;
47-
import java.util.List;
4847
import java.util.Map;
4948
import java.util.Set;
5049

@@ -164,7 +163,9 @@ public void checkDocument(PdfCatalog catalog) {
164163
checkCatalog(catalog);
165164
checkLogicalStructure(catalogDict);
166165
checkForm(catalogDict.getAsDictionary(PdfName.AcroForm));
167-
checkOutlines(catalogDict);
166+
if (catalog.getDocument().hasOutlines()) {
167+
checkOutlines(catalog.getDocument().getOutlines(false));
168+
}
168169
checkPages(catalog.getDocument());
169170
checkOpenAction(catalogDict.get(PdfName.OpenAction));
170171
checkColorsUsages();
@@ -917,34 +918,18 @@ private void checkAnnotations(PdfDictionary page) {
917918
}
918919
}
919920

920-
private void checkOutlines(PdfDictionary catalogDict){
921-
PdfDictionary outlines = catalogDict.getAsDictionary(PdfName.Outlines);
922-
if (outlines != null) {
923-
for (PdfDictionary outline : getOutlines(outlines)) {
924-
PdfDictionary action = outline.getAsDictionary(PdfName.A);
925-
if (action != null) {
926-
checkAction(action);
927-
}
921+
private void checkOutlines(PdfOutline outline){
922+
if (outline != null) {
923+
final PdfDictionary action = outline.getContent().getAsDictionary(PdfName.A);
924+
if (action != null) {
925+
checkAction(action);
926+
}
927+
for (PdfOutline child : outline.getAllChildren()) {
928+
checkOutlines(child);
928929
}
929930
}
930931
}
931932

932-
private List<PdfDictionary> getOutlines(PdfDictionary item) {
933-
List<PdfDictionary> outlines = new ArrayList<>();
934-
outlines.add(item);
935-
936-
PdfDictionary processItem = item.getAsDictionary(PdfName.First);
937-
if (processItem != null){
938-
outlines.addAll(getOutlines(processItem));
939-
}
940-
processItem = item.getAsDictionary(PdfName.Next);
941-
if (processItem != null){
942-
outlines.addAll(getOutlines(processItem));
943-
}
944-
945-
return outlines;
946-
}
947-
948933
private void setCheckerOutputIntent(PdfDictionary outputIntent) {
949934
if (outputIntent != null) {
950935
pdfAOutputIntentDestProfile = outputIntent.getAsStream(PdfName.DestOutputProfile);

pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfACheckerTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ This file is part of the iText (R) project.
4545
import com.itextpdf.kernel.pdf.canvas.CanvasGraphicsState;
4646
import com.itextpdf.kernel.pdf.colorspace.PdfColorSpace;
4747
import com.itextpdf.pdfa.PdfADocument;
48+
import com.itextpdf.test.AssertUtil;
4849
import com.itextpdf.test.ExtendedITextTest;
4950
import com.itextpdf.test.annotations.type.UnitTest;
5051

@@ -69,6 +70,13 @@ public void before() {
6970
pdfAChecker.setFullCheckMode(true);
7071
}
7172

73+
@Test
74+
public void checkPdfWithHugeAmountOfOutlinesTest() throws IOException {
75+
try(PdfDocument pdf = new PdfDocument(new PdfReader(SOURCE_FOLDER + "outlineStackOverflowTest01.pdf"))) {
76+
AssertUtil.doesNotThrow(() -> pdfAChecker.checkDocument(pdf.getCatalog()));
77+
}
78+
}
79+
7280
@Test
7381
public void checkAppearanceStreamsWithCycle() throws IOException {
7482
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
Binary file not shown.

0 commit comments

Comments
 (0)