[Reproducible-commits] [strip-nondeterminism] 02/03: Rewrite PNG handler to support bailing out on invalid header lengths
Chris Lamb
chris at chris-lamb.co.uk
Tue Jul 19 16:32:25 UTC 2016
This is an automated email from the git hooks/post-receive script.
lamby pushed a commit to branch master
in repository strip-nondeterminism.
commit 311c913d452e1811531c2bfeeb631c024819d19a
Author: Chris Lamb <lamby at debian.org>
Date: Tue Jul 19 18:29:51 2016 +0200
Rewrite PNG handler to support bailing out on invalid header lengths
---
lib/File/StripNondeterminism/handlers/png.pm | 60 +++++++++++++++++++++-------
1 file changed, 45 insertions(+), 15 deletions(-)
diff --git a/lib/File/StripNondeterminism/handlers/png.pm b/lib/File/StripNondeterminism/handlers/png.pm
index 6dcf204..7fd0d7c 100644
--- a/lib/File/StripNondeterminism/handlers/png.pm
+++ b/lib/File/StripNondeterminism/handlers/png.pm
@@ -50,16 +50,33 @@ sub text_chunk {
sub normalize {
my ($filename) = @_;
- my $canonical_time = $File::StripNondeterminism::canonical_time;
-
my $tempfile = File::Temp->new(DIR => dirname($filename));
+ open(my $fh, '+<', $filename) or die "$filename: open: $!";
+
+ if (_normalize($filename, $fh, $tempfile)) {
+ chmod((stat($fh))[2] & 07777, $tempfile->filename);
+ rename($tempfile->filename, $filename)
+ or die "$filename: unable to overwrite: rename: $!";
+ }
+
+ $tempfile->unlink_on_destroy(0);
+
+ close $fh;
+}
+
+sub _normalize {
+ my ($filename, $fh, $tempfile) = @_;
+
+ my $canonical_time = $File::StripNondeterminism::canonical_time;
+
my $buf;
+ my $changed;
my $bytes_read;
- open(my $fh, '+<', $filename) or die "$filename: open: $!";
read($fh, my $magic, 8); $magic eq "\x89PNG\r\n\x1a\n"
or die "$filename: does not appear to be a PNG";
+
print $tempfile $magic;
while (read($fh, my $header, 8) == 8) {
@@ -67,27 +84,45 @@ sub normalize {
# Include the trailing CRC when reading
$len += 4;
- # We cannot trust the value of $len, so we only read(2) if it
- # has a sane size.
+
+ # We cannot trust the value of $len so we cannot simply read
+ # that many bytes in memory. Therefore rely on a sane value
+ # for a "header" and hope that matches everything.
if ($len < 4096) {
- read $fh, my $data, $len + 4;
+ my $bytes_read = read($fh, my $data, $len);
+
+ if ($bytes_read != $len) {
+ warn "$filename: invalid length in $type header";
+ return 0;
+ }
if ($type eq "tIME") {
print $tempfile time_chunk($canonical_time) if defined($canonical_time);
+ $changed = 1;
next;
} elsif (($type =~ /[tiz]EXt/) && ($data =~ /^(date:[^\0]+|Creation Time)\0/)) {
print $tempfile text_chunk($1, strftime("%Y-%m-%dT%H:%M:%S-00:00",
gmtime($canonical_time))) if defined($canonical_time);
+ $changed = 1;
next;
}
}
- # Read/write in chunks
print $tempfile $header;
- while (($len > 0) && ($bytes_read = read($fh, $buf, 4096))) {
- $len = $len - $bytes_read;
+
+ while ($len > 0) {
+ # Can't trust $len so read data part in chunks
+ $bytes_read = read($fh, $buf, 4096);
+
+ if ($bytes_read == 0) {
+ warn "$filename: invalid length in $type header";
+ return 0;
+ }
+
print $tempfile $buf;
+ $len -= $bytes_read;
}
+ defined($bytes_read) or die "$filename: read failed: $!";
# Stop processing immediately in case there's garbage after the
# PNG datastream. (https://bugs.debian.org/802057)
@@ -103,12 +138,7 @@ sub normalize {
}
defined($bytes_read) or die "$filename: read failed: $!";
- chmod((stat($fh))[2] & 07777, $tempfile->filename);
- rename($tempfile->filename, $filename)
- or die "$filename: unable to overwrite: rename: $!";
- $tempfile->unlink_on_destroy(0);
-
- close $fh;
+ return $changed;
}
1;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/strip-nondeterminism.git
More information about the Reproducible-commits
mailing list