summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorbrian m. carlson <sandals@crustytoothpaste.net>2016-11-19 03:38:48 +0000
committerbrian m. carlson <sandals@crustytoothpaste.net>2016-11-19 03:38:48 +0000
commit669985f97d84b6bbdb449744310a27b5519d06fc (patch)
tree12dc938b38ffc0cd4eda60031bf666f6c2f15c4d /bin
parent831515692ddb5a9bc5211a71bd1d29e34e4563f9 (diff)
Produce reproducible PDFs.
Set the CreationDate in the document info dictionary to the epoch, and replace the date entries in the XMP metadata with spaces. Finally, generate the file identifier based on an SHA-256 hash of the XSL-FO file. Adobe generally uses MD5 for this purpose, but the specification is silent on the size of the identifier, so use something secure.
Diffstat (limited to 'bin')
-rwxr-xr-xbin/strip-date32
1 files changed, 32 insertions, 0 deletions
diff --git a/bin/strip-date b/bin/strip-date
new file mode 100755
index 0000000..0b28079
--- /dev/null
+++ b/bin/strip-date
@@ -0,0 +1,32 @@
+#!/usr/bin/ruby
+
+id = ARGV[0].upcase
+state = :idle
+$stdin.binmode
+$stdin.each do |line|
+ case state
+ when :idle
+ if line =~ /^(\d+) (\d+) obj/
+ state = :obj
+ elsif line == "trailer\n"
+ state = :trailerobj
+ elsif line == "stream\n"
+ state = :in_stream
+ end
+ when :obj
+ state = line == "<<\n" ? :in_obj : :idle
+ when :trailerobj
+ state = line == "<<\n" ? :in_trailerobj : :idle
+ when :in_obj
+ state = :idle if line == ">>\n"
+ line.sub!(/^(\/\S+Date\s+)\(D:\d+Z\)/, '\1(D:19700101000000Z)')
+ when :in_trailerobj
+ state = :idle if line == ">>\n"
+ line.sub!(/^(\s+\/ID\s+)\[.*/, "\\1[<#{id}> <#{id}>]")
+ when :in_stream
+ state = :idle if line == "endstream\n"
+ line.sub!(/^<(dc:date|xmp:(?:Metadata|Create)Date)>.*<\/\1>/,
+ ' ' * (line.chomp.length))
+ end
+ $stdout.print line
+end