CAM::PDF v1.54 fixes appendPDF bug

I maintain the open source CAM::PDF Perl library in my free time. This library, originally authored by me at Clotho Advanced Media starting in 2002, is a high-performance low-level PDF editing tool. It doesn’t have support for sophisticated authoring tasks (see PDF::API2 for that!) but it is good for utility work like concatenating two PDFs together or deleting pages from a document or encrypting a PDF.

I just fixed a bug where appending a big PDF to a small one (“big” in terms of number of internal objects, which correlates with page count or byte count but is subtly different) often went wrong because I generated object ID numbers by simply incrementing a counter in the small PDF. Sometimes, that counter matched IDs in the bigger PDF, but those IDs are supposed to be unique per document, so things went badly. This bug is now fixed by simply taking the max ID of the two docs as the new counter value before incrementing to make a new ID number.

I never stumbled on the bug in my own work because I always appended (or prepended) the smaller doc to the larger one for performance reasons. CAM::PDF v1.54 is on it’s way to CPAN as I type this.

I’m grateful to Charlie Katz of the Harvard-Smithsonian Center for Astrophysics for providing me with a simple test case that exhibits the problem!

Perl is my calculator

When I want to do some quick math, I find it easier to type a quick Perl command than to launch a calculator app. I always have or Cygwin rxvt open, so I type something like this:

perl -le 'print 32139 + 92176'

which yields the copy-pasteable result:


There are possible faster solutions, like Google (try typing “20 + 20” in your search bar — down arrow, select-all and copy) or Quicksilver‘s math mode on Mac. But Perl is in my muscle memory, and I can quick solutions like appending the results to a file without even thinking about it.

In the command above, I’ve included two flags: -l and -e. -l is shorthand to put a newline at the end of every print statement. -e tells Perl that the next argument will be a script to execute.