Author: tilman
Date: Fri Sep 12 17:48:22 2025
New Revision: 1928374
Log:
PDFBOX-6067: check /ParentTree against /K tree; catch empty set
Modified:
pdfbox/branches/3.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java
Modified:
pdfbox/branches/3.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java
==============================================================================
---
pdfbox/branches/3.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java
Fri Sep 12 15:17:12 2025 (r1928373)
+++
pdfbox/branches/3.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java
Fri Sep 12 17:48:22 2025 (r1928374)
@@ -750,7 +750,8 @@ class PDFMergerUtilityTest
}
}
// actual count may be larger if last element is null, e.g.
PDFBOX-4408
- assertTrue(set.last() <= array.size() - 1);
+ // set can be empty, see last page of pdf_32000_2008.pdf
+ assertTrue(set.isEmpty() || set.last() <= array.size() - 1);
}
for (PDAnnotation ann : page.getAnnotations())
{
@@ -875,6 +876,34 @@ class PDFMergerUtilityTest
assertNotNull(structureTreeRoot.getK());
checkElement(pageTree, structureTreeRoot.getK(),
structureTreeRoot.getCOSObject());
checkForIDTreeOrphans(pageTree, structureTreeRoot);
+ checkParentTreeAgainstK(structureTreeRoot);
+ }
+
+ private void checkParentTreeAgainstK(PDStructureTreeRoot
structureTreeRoot) throws IOException
+ {
+ // check that elements in the /ParentTree are in the /K tree
+ ElementCounter elementCounter = new ElementCounter();
+ elementCounter.walk(structureTreeRoot.getK());
+ Map<Integer, COSObjectable> numberTreeAsMap =
PDFMergerUtility.getNumberTreeAsMap(structureTreeRoot.getParentTree());
+ for (Map.Entry<Integer, COSObjectable> entry :
numberTreeAsMap.entrySet())
+ {
+ PDParentTreeValue val = (PDParentTreeValue) entry.getValue(); //
array or dictionary
+ COSBase base = val.getCOSObject();
+ if (base instanceof COSArray)
+ {
+ COSArray array = (COSArray) base;
+ for (int i = 0; i < array.size(); ++i)
+ {
+ COSBase arrayElement = array.getObject(i);
+ if (arrayElement instanceof COSDictionary)
+ {
+ assertTrue(elementCounter.set.contains(arrayElement),
+ "Element " + entry.getKey() + ":" + i + " from
/ParentTree missing in /K ");
+ }
+ }
+ }
+ // can't check this COSDictionary; ElementsCounter only counts
those with a /Pg entry
+ }
}
private void checkForIDTreeOrphans(PDPageTree pageTree,
PDStructureTreeRoot structureTreeRoot)