From: Steve Peters Date: Thu, 25 May 2006 13:48:56 +0000 (+0000) Subject: Upgrade to Digest-SHA-5.38. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c7e5c26655f2f74886cec5bfe7ed3fa34e3b2b2b;p=p5sagit%2Fp5-mst-13.2.git Upgrade to Digest-SHA-5.38. p4raw-id: //depot/perl@28306 --- diff --git a/ext/Digest/SHA/Changes b/ext/Digest/SHA/Changes index 18d1213..5f01e1c 100644 --- a/ext/Digest/SHA/Changes +++ b/ext/Digest/SHA/Changes @@ -1,5 +1,17 @@ Revision history for Perl extension Digest::SHA. +5.38 Thu May 25 02:02:02 MST 2006 + - added new capabilities to the "addfile" method + -- now able to accept file names as well as handles + -- includes mode for portable digest calculation + -- thanks to Adam Kennedy for emails and ideas + ref. File::LocalizeNewlines + - used expanded addfile interface to simplify shasum (sumfile) + -- regex a tad less general than 5.37, but handles all + known newline variants in UNIX/Windows/MacOS + - enhanced WARNING messages from shasum checkfile processing + -- to mimic behavior of md5sum + 5.37 Mon May 8 04:30:09 MST 2006 - modified shasum to avoid file slurping (ref. sub sumfile) - improved error handling of checksum files in shasum diff --git a/ext/Digest/SHA/README b/ext/Digest/SHA/README index fcdea0f..2f833d6 100644 --- a/ext/Digest/SHA/README +++ b/ext/Digest/SHA/README @@ -1,4 +1,4 @@ -Digest::SHA version 5.37 +Digest::SHA version 5.38 ======================== Digest::SHA is a complete implementation of the NIST Secure Hash diff --git a/ext/Digest/SHA/SHA.pm b/ext/Digest/SHA/SHA.pm index 38f34a2..0ba9347 100644 --- a/ext/Digest/SHA/SHA.pm +++ b/ext/Digest/SHA/SHA.pm @@ -1,10 +1,12 @@ package Digest::SHA; +require 5.006000; + use strict; use warnings; use integer; -our $VERSION = '5.36_01'; +our $VERSION = '5.38_01'; require Exporter; our @ISA = qw(Exporter); @@ -23,13 +25,14 @@ our @EXPORT_OK = qw( # If possible, inherit from Digest::base (which depends on MIME::Base64) +*addfile = \&Addfile; + eval { require MIME::Base64; require Digest::base; push(@ISA, 'Digest::base'); }; if ($@) { - *addfile = \&Addfile; *hexdigest = \&Hexdigest; *b64digest = \&B64digest; } @@ -85,25 +88,66 @@ sub add_bits { return($self); } -# local copy of "addfile" in case Digest::base not installed +sub _bail { + my $msg = shift; + + require Carp; + Carp::croak("$msg: $!"); +} -sub Addfile { # this is "addfile" from Digest::base 1.00 +sub _addfile { # this is "addfile" from Digest::base 1.00 my ($self, $handle) = @_; my $n; my $buf = ""; while (($n = read($handle, $buf, 4096))) { - $self->add($buf); - } - unless (defined $n) { - require Carp; - Carp::croak("Read failed: $!"); + $self->add($buf); } + _bail("Read failed") unless defined $n; $self; } +sub Addfile { + my ($self, $file, $mode) = @_; + + if (ref(\$file) eq 'GLOB') { return(_addfile($self, $file)) } + + $mode = defined($mode) ? $mode : ""; + my ($binary, $portable) = map { $_ eq $mode } ("b", "p"); + my $text = -T $file; + + local *F; + _bail("Open failed") unless open(F, "<$file"); + binmode(F) if $binary || $portable; + + unless ($portable && $text) { + $self->_addfile(*F); + close(F); + return($self); + } + + my ($n1, $n2); + my ($buf1, $buf2) = ("", ""); + + while (($n1 = read(F, $buf1, 4096))) { + while (substr($buf1, -1) eq "\015") { + $n2 = read(F, $buf2, 4096); + _bail("Read failed") unless defined $n2; + last unless $n2; + $buf1 .= $buf2; + } + $buf1 =~ s/\015?\015\012/\012/g; # DOS/Windows + $buf1 =~ s/\015/\012/g; # Apple/MacOS 9 + $self->add($buf1); + } + _bail("Read failed") unless defined $n1; + close(F); + + $self; +} + sub dump { my $self = shift; my $file = shift || ""; @@ -156,7 +200,10 @@ In programs: $sha = Digest::SHA->new($alg); $sha->add($data); # feed data into stream + $sha->addfile(*F); + $sha->addfile($filename); + $sha->add_bits($bits); $sha->add_bits($data, $nbits); @@ -409,8 +456,32 @@ So, the following two statements do the same thing: Reads from I until EOF, and appends that data to the current state. The return value is the updated object itself. -This method is inherited if L is installed on your -system. Otherwise, a functionally equivalent substitute is used. +=item B + +Reads the contents of I<$filename>, and appends that data to the current +state. The return value is the updated object itself. + +By default, I<$filename> is simply opened and read; no special modes +or I/O disciplines are used. To change this, set the optional I<$mode> +argument to one of the following values: + +=over 4 + +=item B<"b"> read file in binary mode + +=item B<"p"> use portable mode + +=back + +The "p" mode is handy since it ensures that the digest value of +I<$filename> will be the same when computed on different operating +systems. It accomplishes this by internally translating all newlines +in text files to UNIX format before calculating the digest; on the other +hand, binary files are read in raw mode with no translation whatsoever. + +For a fuller discussion of newline formats, refer to CPAN module +L. Its "universal line separator" regex forms +the basis of I's portable mode processing. =item B @@ -539,6 +610,7 @@ The author is particularly grateful to Jeffrey Friedl Robert Gilmour Brian Gladman + Adam Kennedy Andy Lester Alex Muntada Steve Peters diff --git a/ext/Digest/SHA/bin/shasum b/ext/Digest/SHA/bin/shasum index 0c28719..fdb615b 100755 --- a/ext/Digest/SHA/bin/shasum +++ b/ext/Digest/SHA/bin/shasum @@ -4,8 +4,8 @@ # # Copyright (C) 2003-2006 Mark Shelor, All Rights Reserved # - # Version: 5.37 - # Mon May 8 04:30:09 MST 2006 + # Version: 5.38 + # Thu May 25 02:02:02 MST 2006 =head1 NAME @@ -22,7 +22,7 @@ shasum - Print or Check SHA Checksums -b, --binary read files in binary mode (default on DOS/Windows) -c, --check check SHA sums against given list -p, --portable read files in portable mode - produces same digest on Windows/Unix/MacOS + produces same digest on Windows/Unix/MacOS 9 -t, --text read files in text mode (default) The following two options are useful only when verifying checksums: @@ -52,7 +52,7 @@ L. use strict; use Getopt::Long; -my $VERSION = "5.37"; +my $VERSION = "5.38"; # Try to use Digest::SHA, since it's faster. If not installed, @@ -79,10 +79,10 @@ sub usage { $msg = "" unless defined $msg; if ($err) { - print STDERR "$msg", "Type shasum -h for help\n"; + warn($msg . "Type shasum -h for help\n"); exit($err); } - print STDOUT <<'END_OF_USAGE'; + print <<'END_OF_USAGE'; Usage: shasum [OPTION] [FILE]... or: shasum [OPTION] --check [FILE] Print or check SHA checksums. @@ -92,7 +92,7 @@ With no FILE, or when FILE is -, read standard input. -b, --binary read files in binary mode (default on DOS/Windows) -c, --check check SHA sums against given list -p, --portable read files in portable mode - produces same digest on Windows/Unix/MacOS + produces same digest on Windows/Unix/MacOS 9 -t, --text read files in text mode (default) The following two options are useful only when verifying checksums: @@ -132,11 +132,11 @@ GetOptions( usage(0) if $help; -usage(1, "ambiguous file mode\n") +usage(1, "Ambiguous file mode\n") if scalar(grep { defined $_ } ($binary, $portable, $text)) > 1; -usage(1, "warn option used only when verifying checksums\n") +usage(1, "shasum: --warn option used only when verifying checksums\n") if $warn && !$check; -usage(1, "status option used only when verifying checksums\n") +usage(1, "shasum: --status option used only when verifying checksums\n") if $status && !$check; @@ -144,7 +144,7 @@ usage(1, "status option used only when verifying checksums\n") $alg = 1 unless $alg; grep { $_ == $alg } (1, 224, 256, 384, 512) - or usage(1, "unrecognized algorithm\n"); + or usage(1, "Unrecognized algorithm\n"); # Display version information if requested @@ -157,13 +157,13 @@ if ($version) { # Try to figure out if the OS is DOS-like. If it is, # default to binary mode when reading files, unless - # explicitly overriden by command line "text" or - # "portable" options. + # explicitly overriden by command line "--text" or + # "--portable" options. my $isDOSish = ($^O =~ /^(MSWin\d\d|os2|dos|mint|cygwin)$/); if ($isDOSish) { $binary = 1 unless $text || $portable } -my $mode = $binary ? '*' : ($portable ? '?' : ' '); +my $modesym = $binary ? '*' : ($portable ? '?' : ' '); # Read from STDIN (-) if no files listed on command line @@ -176,27 +176,24 @@ my $mode = $binary ? '*' : ($portable ? '?' : ' '); sub sumfile { my $file = shift; - local *F; - return unless open(F, "<$file"); - binmode(F) if $binary || $portable; + unless (-e $file) { + warn "shasum: $file: No such file or directory\n"; + return; + } + unless (-r $file) { + warn "shasum: $file: FAILED open or read\n"; + return; + } my $digest = $module->new($alg); - if ($portable && -T $file) { - local $/ = \4096; - while (defined (my $rec = )) { - while (substr($rec, -1) eq "\015") { - defined (my $extra = ) or last; - $rec .= $extra; - } - $rec =~ s/\015+\012/\012/g; - $rec =~ s/\015/\012/g; - $digest->add($rec); - } + unless ($digest) { + warn "shasum: $file: FAILED digest creation\n"; + return; } - else { $digest->addfile(*F) } - close(F); - $digest->hexdigest; + my $readmode = $portable ? 'p' : ($binary ? 'b' : ''); + + $digest->addfile($file, $readmode)->hexdigest; } @@ -209,37 +206,41 @@ my %len2alg = (40 => 1, 56 => 224, 64 => 256, 96 => 384, 128 => 512); if ($check) { my $checkfile = shift(@ARGV); - my $err = 0; + my ($err, $read_errs, $match_errs) = (0, 0, 0); + my ($num_files, $num_checksums) = (0, 0); my ($fh, $sum, $fname, $rsp); die "shasum: $checkfile: No such file or directory\n" unless open($fh, "<$checkfile"); while (<$fh>) { s/\s+$//; - ($sum, $mode, $fname) = /^(\S+) (.)(.*)$/; - unless (-e $fname) { - warn "shasum: $fname: No such file or directory\n"; - next; - } + ($sum, $modesym, $fname) = /^(\S+) (.)(.*)$/; ($binary, $portable, $text) = - map { $_ eq $mode } ('*', '?', ' '); + map { $_ eq $modesym } ('*', '?', ' '); unless ($alg = $len2alg{length($sum)}) { warn("shasum: $checkfile: $.: improperly " . "formatted SHA checksum line\n") if $warn; next; } - $rsp = "$fname: "; + $rsp = "$fname: "; $num_files++; unless (my $digest = sumfile($fname)) { $rsp .= "FAILED open or read\n"; - $err = 1; + $err = 1; $read_errs++; } else { + $num_checksums++; if (lc($sum) eq $digest) { $rsp .= "OK\n" } - else { $rsp .= "FAILED\n"; $err = 1 } + else { $rsp .= "FAILED\n"; $err = 1; $match_errs++ } } print $rsp unless $status; } close($fh); + unless ($status) { + warn("shasum: WARNING: $read_errs of $num_files listed " . + "files could not be read\n") if $read_errs; + warn("shasum: WARNING: $match_errs of $num_checksums " . + "computed checksums did NOT match\n") if $match_errs; + } exit($err); } @@ -248,9 +249,9 @@ if ($check) { for my $arg (@ARGV) { if (-d $arg) { - print STDERR "shasum: $arg: Is a directory\n"; + warn "shasum: $arg: Is a directory\n"; next; } - next unless my $digest = sumfile($arg); - print "$digest $mode", "$arg\n"; + my $digest = sumfile($arg) or next; + print "$digest $modesym$arg\n"; } diff --git a/ext/Digest/SHA/src/hmac.c b/ext/Digest/SHA/src/hmac.c index e423bd5..be2fe64 100644 --- a/ext/Digest/SHA/src/hmac.c +++ b/ext/Digest/SHA/src/hmac.c @@ -5,8 +5,8 @@ * * Copyright (C) 2003-2006 Mark Shelor, All Rights Reserved * - * Version: 5.37 - * Mon May 8 04:30:09 MST 2006 + * Version: 5.38 + * Thu May 25 02:02:02 MST 2006 * */ diff --git a/ext/Digest/SHA/src/hmac.h b/ext/Digest/SHA/src/hmac.h index 43a7afa..221c09f 100644 --- a/ext/Digest/SHA/src/hmac.h +++ b/ext/Digest/SHA/src/hmac.h @@ -5,8 +5,8 @@ * * Copyright (C) 2003-2006 Mark Shelor, All Rights Reserved * - * Version: 5.37 - * Mon May 8 04:30:09 MST 2006 + * Version: 5.38 + * Thu May 25 02:02:02 MST 2006 * */ diff --git a/ext/Digest/SHA/src/sha.c b/ext/Digest/SHA/src/sha.c index 47a18fe..7b4faa4 100644 --- a/ext/Digest/SHA/src/sha.c +++ b/ext/Digest/SHA/src/sha.c @@ -5,8 +5,8 @@ * * Copyright (C) 2003-2006 Mark Shelor, All Rights Reserved * - * Version: 5.37 - * Mon May 8 04:30:09 MST 2006 + * Version: 5.38 + * Thu May 25 02:02:02 MST 2006 * */ diff --git a/ext/Digest/SHA/src/sha.h b/ext/Digest/SHA/src/sha.h index 95597d3..bf850c4 100644 --- a/ext/Digest/SHA/src/sha.h +++ b/ext/Digest/SHA/src/sha.h @@ -5,8 +5,8 @@ * * Copyright (C) 2003-2006 Mark Shelor, All Rights Reserved * - * Version: 5.37 - * Mon May 8 04:30:09 MST 2006 + * Version: 5.38 + * Thu May 25 02:02:02 MST 2006 * */ diff --git a/ext/Digest/SHA/t/2-nist-sha-oo.t b/ext/Digest/SHA/t/2-nist-sha-oo.t index deefce9..c1a6b3e 100644 --- a/ext/Digest/SHA/t/2-nist-sha-oo.t +++ b/ext/Digest/SHA/t/2-nist-sha-oo.t @@ -20,7 +20,7 @@ BEGIN { "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" ); - plan tests => 1 + scalar(@vec); + plan tests => 5 + scalar(@vec); } # attempt to use an invalid algorithm, and check for failure @@ -46,6 +46,37 @@ ok($ctx->clone->add("b", "c")->b64digest, $rsp); $rsp = shift(@vec); open(FILE, "<$file"); binmode(FILE); -ok($ctx->addfile(*FILE)->hexdigest, $rsp); +ok($ctx->clone->addfile(*FILE)->hexdigest, $rsp); close(FILE); + + # test addfile using file name instead of handle + +ok($ctx->addfile($file, "b")->hexdigest, $rsp); + + # test addfile portable mode + +open(FILE, ">$file"); +binmode(FILE); +print FILE "abc\012" x 2048; # using UNIX newline +close(FILE); + +ok($ctx->new(1)->addfile($file, "p")->hexdigest, + "d449e19c1b0b0c191294c8dc9fa2e4a6ff77fc51"); + +open(FILE, ">$file"); +binmode(FILE); +print FILE "abc\015\012" x 2048; # using DOS/Windows newline +close(FILE); + +ok($ctx->new(1)->addfile($file, "p")->hexdigest, + "d449e19c1b0b0c191294c8dc9fa2e4a6ff77fc51"); + +open(FILE, ">$file"); +binmode(FILE); +print FILE "abc\015" x 2048; # using Apple/Mac newline +close(FILE); + +ok($ctx->new(1)->addfile($file, "p")->hexdigest, + "d449e19c1b0b0c191294c8dc9fa2e4a6ff77fc51"); + unlink($file);