A quick summary
Our latest PDF Library has a few important aspects to it. The most significant is that this release fixes a security vulnerability relating to JavaScript. If you're a customer we should have emailed you already about this, so if you haven't got this already then please contact sales@bfo.com and they'll give you the details.
You can read the Changelog for the full list, but the main aspects of this release are:
This last one deserves a bit more of an explanation. Many users of the PDF Library find themselves merging PDF documents in one way or another, in particular when a document has form fields. Quite a common operation is to move all a field's annotations from one page to another, and in previous builds this could lead to a contradiction:
List annots1 = page1.getAnnotations(); List annots2 = page2.getAnnotations(); // Move all annotations from page1 to page2 annots2.getAnnotations().addAll(annots1); // Contradiction ahead: page 1's annotation not on page 1! assert annots1.isEmpty(); // fails! PDFAnnotation annot = (PDFAnnotation)annots1.get(0); assert annot.getPage() == page1; // fails!
The problem comes about because while in general, an item in a java.util.List
can belong to more than one list, an annotation can only be on one page at a time.
Adding all the annotations from page 2 to page 1's list should remove them from page
2, but if you try to do that with a normal list you'll quickly come up against a ConcurrentModificationException. The same problem exists when moving widgets between form fields.
We've finally got a a solution to this in the shape of a new List implementation, which manages the moving of items from one list to another without any ConcurrentModificationExceptions. Your Iterators in the following will work properly:
List annots1 = page1.getAnnotations(); List annots2 = page2.getAnnotations(); for (Iterator i = annots1.iterator();i.hasNext();) { annots2.add(i.next()); i.remove(); // optional - it's going to happen anyway } assert annots1.isEmpty();
And if you're just copying the annotation list to a regular java.util.List
, everything will work as normal:
List annots1 = page1.getAnnotations(); List temp = new ArrayList(); for (Iterator i = annots1.iterator();i.hasNext();) { temp.add(i.next()); } assert annots1.size() == temp.size();
The result is that your PDF's structure is internally consistent all of the time, which clears the way for us to put out some further improvements in a forthcoming release. Watch this space.