Package: strip-nondeterminism Version: 0.003-1 Severity: wishlist Tags: patch User: reproducible-builds@lists.alioth.debian.org Usertags: toolchain timestamps X-Debbugs-Cc: reproducible-builds@lists.alioth.debian.org
Hi, A patch attached with initial support for overriding timestamps in PNG files. Possible limitations: * Other tEXt free-form formats; eg. "date:create" and "date:modify" are ImageMagick specific, apparently * Timestamps in compressed or "international" text chunks (zTXt/iTXt) Regards, -- ,''`. : :' : Chris Lamb `. `'` la...@debian.org / chris-lamb.co.uk `-
From 79a50129221d10bccee38c5e4d8cd6c59e69fd02 Mon Sep 17 00:00:00 2001 From: Chris Lamb <la...@debian.org> Date: Wed, 11 Feb 2015 12:24:49 +0000 Subject: [PATCH] Add initial support for PNG --- lib/File/StripNondeterminism.pm | 6 +++ lib/File/StripNondeterminism/handlers/png.pm | 81 ++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 lib/File/StripNondeterminism/handlers/png.pm diff --git a/lib/File/StripNondeterminism.pm b/lib/File/StripNondeterminism.pm index 8f4d4b7..8d17640 100644 --- a/lib/File/StripNondeterminism.pm +++ b/lib/File/StripNondeterminism.pm @@ -27,6 +27,7 @@ use File::StripNondeterminism::handlers::jar; use File::StripNondeterminism::handlers::javadoc; use File::StripNondeterminism::handlers::pe; use File::StripNondeterminism::handlers::pearregistry; +use File::StripNondeterminism::handlers::png; use File::StripNondeterminism::handlers::javaproperties; use File::StripNondeterminism::handlers::zip; @@ -73,6 +74,10 @@ sub get_normalizer_for_file { if (m/\.(exe|dll|cpl|ocx|sys|scr|drv|efi|fon)/ && _get_file_type($_) =~ m/PE32.? executable/) { return \&File::StripNondeterminism::handlers::pe::normalize; } + # PNG + if (m/\.png$/ && _get_file_type($_) =~ m/PNG image data/) { + return \&File::StripNondeterminism::handlers::png::normalize; + } # pom.properties, version.properties if (m/(pom|version)\.properties$/ && File::StripNondeterminism::handlers::javaproperties::is_java_properties_file($_)) { return \&File::StripNondeterminism::handlers::javaproperties::normalize; @@ -92,6 +97,7 @@ sub get_normalizer_by_name { return \&File::StripNondeterminism::handlers::javadoc::normalize if $_ eq 'javadoc'; return \&File::StripNondeterminism::handlers::pe::normalize if $_ eq 'pe'; return \&File::StripNondeterminism::handlers::pearregistry::normalize if $_ eq 'pearregistry'; + return \&File::StripNondeterminism::handlers::png::normalize if $_ eq 'png'; return \&File::StripNondeterminism::handlers::javaproperties::normalize if $_ eq 'javaproperties'; return \&File::StripNondeterminism::handlers::zip::normalize if $_ eq 'zip'; return undef; diff --git a/lib/File/StripNondeterminism/handlers/png.pm b/lib/File/StripNondeterminism/handlers/png.pm new file mode 100644 index 0000000..2b300b3 --- /dev/null +++ b/lib/File/StripNondeterminism/handlers/png.pm @@ -0,0 +1,81 @@ +# +# Copyright 2015 Chris Lamb <la...@debian.org> +# +# This file is part of strip-nondeterminism. +# +# strip-nondeterminism is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# strip-nondeterminism is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with strip-nondeterminism. If not, see <http://www.gnu.org/licenses/>. +# +package File::StripNondeterminism::handlers::png; + +use strict; +use warnings; + +use Fcntl qw/:seek/; +use POSIX qw/strftime/; +use Digest::CRC qw/crc32/; + +sub normalize { + my ($filename) = @_; + + my $buffer = ""; + my $canonical_time = $File::StripNondeterminism::canonical_time // 0; + + open PNG, '+<', $filename + || die "Could not open '$filename' for reading: $!"; + + # Check magic + read PNG, $buffer, 8; + $buffer eq "\x89PNG\r\n\x1a\n" + || die "'$filename' does not appear to be a PNG file"; + + while (1) { + read PNG, $buffer, 8; + last if length($buffer) < 8; + + # Parse chunk header + my ($len, $type) = unpack('Na4', $buffer); + + if ($type eq "tIME") { + my $val = pack('nC5', $canonical_time); + print PNG $val; + print PNG pack('N', crc32($type . $val)); + } elsif ($type eq "tEXt") { + # Read entire field + read PNG, $buffer, $len + 4; + + # Split contents by null byte + if (my ($tag) = $buffer =~ /^(date:[^\0]+)/) { + # Join with new timestamp + my $val = "$tag\0". strftime("%Y-%m-%dT%H:%M:%S%z", + gmtime($canonical_time)); + + # +0100 (%z) -> +01:00 + $val =~ s/(?<=[+-]\d\d)(?=\d\d$)/:/; + + # Seek backwards as we already read the field + seek PNG, -($len + 4), SEEK_CUR; + + print PNG $val; + print PNG pack('N', crc32($type . $val)); + } + } else { + # Skip chunk data and CRC + seek PNG, $len + 4, SEEK_CUR; + } + } + + close PNG; +} + +1; -- 2.1.0
_______________________________________________ Reproducible-builds mailing list Reproducible-builds@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/reproducible-builds