From: Jarkko Hietaniemi Date: Sat, 5 Jul 2003 19:12:21 +0000 (+0000) Subject: Upgrade to Digest::MD5 2.25. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ac70dec105c793ebc869f1418800d67764d2ceb9;p=p5sagit%2Fp5-mst-13.2.git Upgrade to Digest::MD5 2.25. p4raw-id: //depot/perl@20020 --- diff --git a/MANIFEST b/MANIFEST index 4ad1640..870897d 100644 --- a/MANIFEST +++ b/MANIFEST @@ -186,6 +186,7 @@ ext/Digest/MD5/MD5.xs Digest::MD5 extension ext/Digest/MD5/README Digest::MD5 extension Readme ext/Digest/MD5/t/align.t See if Digest::MD5 extension works ext/Digest/MD5/t/badfile.t See if Digest::MD5 extension works +ext/Digest/MD5/t/clone.t See if Digest::MD5 extension works ext/Digest/MD5/t/files.t See if Digest::MD5 extension works ext/Digest/MD5/t/md5-aaa.t See if Digest::MD5 extension works ext/Digest/MD5/t/utf8.t See if Digest::MD5 extension works diff --git a/ext/Digest/MD5/Changes b/ext/Digest/MD5/Changes index a2d6953..cebcd2f 100644 --- a/ext/Digest/MD5/Changes +++ b/ext/Digest/MD5/Changes @@ -1,3 +1,19 @@ +2003-07-04 Gisle Aas + + Release 2.25 + + The $md5->addfile method now croaks if it discovers + errors on the handle after reading from it. This should + make it more difficult to end up with the wrong digest + just because you are to lazy to check the error status + on your file handles after reading from them. + + Improved documentation. + + Sync up with bleadperl; even safer patchlevel include. + + + 2003-03-09 Gisle Aas Release 2.24 diff --git a/ext/Digest/MD5/MD5.pm b/ext/Digest/MD5/MD5.pm index ece02df..cae8f11 100644 --- a/ext/Digest/MD5/MD5.pm +++ b/ext/Digest/MD5/MD5.pm @@ -3,7 +3,7 @@ package Digest::MD5; use strict; use vars qw($VERSION @ISA @EXPORT_OK); -$VERSION = '2.24'; # $Date: 2003/03/09 15:23:10 $ +$VERSION = '2.25'; # $Date: 2003/07/05 05:25:37 $ require Exporter; *import = \&Exporter::import; @@ -43,7 +43,7 @@ Digest::MD5 - Perl interface to the MD5 Algorithm =head1 SYNOPSIS # Functional style - use Digest::MD5 qw(md5 md5_hex md5_base64); + use Digest::MD5 qw(md5 md5_hex md5_base64); $digest = md5($data); $digest = md5_hex($data); @@ -72,80 +72,111 @@ The C module provide a procedural interface for simple use, as well as an object oriented interface that can handle messages of arbitrary length and which can read files directly. -A binary digest will be 16 bytes long. A hex digest will be 32 -characters long. A base64 digest will be 22 characters long. - =head1 FUNCTIONS -The following functions can be exported from the C -module. No functions are exported by default. +The following functions are provided by the C module. +None of these functions are exported by default. =over 4 =item md5($data,...) This function will concatenate all arguments, calculate the MD5 digest -of this "message", and return it in binary form. +of this "message", and return it in binary form. The returned string +will be 16 bytes long. + +The result of md5("a", "b", "c") will be exactly the same as the +result of md5("abc"). =item md5_hex($data,...) -Same as md5(), but will return the digest in hexadecimal form. +Same as md5(), but will return the digest in hexadecimal form. The +length of the returned string will be 32 and it will only contain +characters from this set: '0'..'9' and 'a'..'f'. =item md5_base64($data,...) Same as md5(), but will return the digest as a base64 encoded string. +The length of the returned string will be 22 and it will only contain +characters from this set: 'A'..'Z', 'a'..'z', '0'..'9', '+' and +'/'. -The base64 encoded string returned is not padded to be a multiple of 4 -bytes long. If you want interoperability with other base64 encoded -md5 digests you might want to append the string "==" to the result. +Note that the base64 encoded string returned is not padded to be a +multiple of 4 bytes long. If you want interoperability with other +base64 encoded md5 digests you might want to append the redundant +string redundant "==" to the result. =back =head1 METHODS -The following methods are available: +The object oriented interface to C is described in this +section. After a C object has been created, you will add +data to it and finally ask for the digest in a suitable format. A +single object can be used to calculate multiple digests. + +The following methods are provided: =over 4 =item $md5 = Digest::MD5->new The constructor returns a new C object which encapsulate -the state of the MD5 message-digest algorithm. You can add data to -the object and finally ask for the digest. +the state of the MD5 message-digest algorithm. If called as an instance method (i.e. $md5->new) it will just reset the state the object to the state of a newly created object. No new object is created in this case. -=item $md5->clone - -This is a copy constructor returning a clone of the $md5 object. It is -useful when you do not want to destroy the digests state, but need an -intermediate value of the digest, e.g. when calculating digests -iteratively on a continuous data stream in order to obtain a copy which -may be destroyed. - =item $md5->reset This is just an alias for $md5->new. +=item $md5->clone + +This a copy of the $md5 object. It is useful when you do not want to +destroy the digests state, but need an intermediate value of the +digest, e.g. when calculating digests iteratively on a continuous data +stream. Example: + + my $md5 = Digest::MD5->new; + while (<>) { + $md5->add($_); + print "Line $.: ", $md5->clone->hexdigest, "\n"; + } + =item $md5->add($data,...) The $data provided as argument are appended to the message we calculate the digest for. The return value is the $md5 object itself. +All these lines will have the same effect on the state of the $md5 +object: + + $md5->add("a"); $md5->add("b"); $md5->add("c"); + $md5->add("a")->add("b")->add("c"); + $md5->add("a", "b", "c"); + $md5->add("abc"); + =item $md5->addfile($io_handle) -The $io_handle is read until EOF and the content is appended to the +The $io_handle will be read until EOF and its content appended to the message we calculate the digest for. The return value is the $md5 object itself. -In most cases you want to make sure that the $io_handle is set up to -be in binmode(). +The addfile() method will croak() if it fails reading data for some +reason. If it croaks it is unpredictable what the state of the $md5 +object will be in. The addfile() method might have been able to read +the file partially before it failed. It is probably wise to discard +or reset the $md5 object if this occurs. + +In most cases you want to make sure that the $io_handle is in +C before you pass it as argument to the addfile() method. =item $md5->digest -Return the binary digest for the message. +Return the binary digest for the message. The returned string will be +16 bytes long. Note that the C operation is effectively a destructive, read-once operation. Once it has been performed, the C @@ -155,12 +186,17 @@ digest without reseting the digest state. =item $md5->hexdigest -Same as $md5->digest, but will return the digest in hexadecimal form. +Same as $md5->digest, but will return the digest in hexadecimal +form. The length of the returned string will be 32 and it will only +contain characters from this set: '0'..'9' and 'a'..'f'. =item $md5->b64digest Same as $md5->digest, but will return the digest as a base64 encoded -string. +string. The length of the returned string will be 22 and it will only +contain characters from this set: 'A'..'Z', 'a'..'z', '0'..'9', '+' +and '/'. + The base64 encoded string returned is not padded to be a multiple of 4 bytes long. If you want interoperability with other base64 encoded @@ -177,12 +213,11 @@ function (or one of its cousins): use Digest::MD5 qw(md5_hex); print "Digest is ", md5_hex("foobarbaz"), "\n"; -The above example would print out the message +The above example would print out the message: Digest is 6df23dc03f9b54cc38a0fc1483df6e21 -provided that the implementation is working correctly. The same -checksum can also be calculated in OO style: +The same checksum can also be calculated in OO style: use Digest::MD5; @@ -266,9 +301,9 @@ modify it under the same terms as Perl itself. Copyright 1995-1996 Neil Winton. Copyright 1991-1992 RSA Data Security, Inc. -The MD5 algorithm is defined in RFC 1321. The basic C code -implementing the algorithm is derived from that in the RFC and is -covered by the following copyright: +The MD5 algorithm is defined in RFC 1321. This implementation is +derived from the reference C code in RFC 1321 which is covered by +the following copyright statement: =over 4 @@ -303,9 +338,9 @@ licenses. =head1 AUTHORS -The original MD5 interface was written by Neil Winton +The original C interface was written by Neil Winton (C). -This release was made by Gisle Aas +The C module is written by Gisle Aas . =cut diff --git a/ext/Digest/MD5/MD5.xs b/ext/Digest/MD5/MD5.xs index 3b3c685..0bf05f0 100644 --- a/ext/Digest/MD5/MD5.xs +++ b/ext/Digest/MD5/MD5.xs @@ -1,4 +1,4 @@ -/* $Id: MD5.xs,v 1.37 2003/03/09 15:20:43 gisle Exp $ */ +/* $Id: MD5.xs,v 1.39 2003/07/05 05:25:37 gisle Exp $ */ /* * This library is free software; you can redistribute it and/or @@ -636,10 +636,17 @@ addfile(self, fh) XSRETURN(1); /* self */ } - /* Process blocks until EOF */ + /* Process blocks until EOF or error */ while ( (n = PerlIO_read(fh, buffer, sizeof(buffer)))) { MD5Update(context, buffer, n); } + + if (PerlIO_error(fh)) { + croak("Reading from filehandle failed"); + } + } + else { + croak("No filehandle passed"); } XSRETURN(1); /* self */ diff --git a/ext/Digest/MD5/t/badfile.t b/ext/Digest/MD5/t/badfile.t index d066d0d..32fc6fe 100644 --- a/ext/Digest/MD5/t/badfile.t +++ b/ext/Digest/MD5/t/badfile.t @@ -1,7 +1,7 @@ # Digest::MD5 2.07 and older used to trigger a core dump when # passed an illegal file handle that failed to open. -print "1..2\n"; +print "1..3\n"; use Digest::MD5 (); @@ -11,11 +11,22 @@ eval { use vars qw(*FOO); $md5->addfile(*FOO); }; -print "not " unless $@ =~ /^Bad filehandle: FOO/; +print "not " unless $@ =~ /^Bad filehandle: FOO at/; print "ok 1\n"; -open(BAR, "none-existing-file.$$"); -$md5->addfile(*BAR); - -print "not " unless $md5->hexdigest eq "d41d8cd98f00b204e9800998ecf8427e"; +open(BAR, "no-existing-file.$$"); +eval { + $md5->addfile(*BAR); +}; +print "not " unless $@ =~ /^No filehandle passed at/; print "ok 2\n"; + +open(BAR, ">no-existing-file.$$") || die; +eval { + $md5->addfile(*BAR); +}; +print "not " unless $@ =~ /^Reading from filehandle failed at/; +print "ok 3\n"; + +close(BAR); +unlink("no-existing-file.$$"); diff --git a/ext/Digest/MD5/t/clone.t b/ext/Digest/MD5/t/clone.t new file mode 100644 index 0000000..56382af --- /dev/null +++ b/ext/Digest/MD5/t/clone.t @@ -0,0 +1,41 @@ +#!perl -w + +print "1..6\n"; + +use strict; +use Digest::MD5 qw(md5_hex); + +my $a = Digest::MD5->new; +$a->add("a"); +my $b = $a->clone; + +print "not " unless $b->clone->hexdigest eq md5_hex("a"); +print "ok 1\n"; + +$a->add("a"); +print "not " unless $a->hexdigest eq md5_hex("aa"); +print "ok 2\n"; + +print "not " unless $a->hexdigest eq md5_hex(""); +print "ok 3\n"; + +$b->add("b"); +print "not " unless $b->clone->hexdigest eq md5_hex("ab"); +print "ok 4\n"; + +$b->add("c"); +print "not " unless $b->clone->hexdigest eq md5_hex("abc"); +print "ok 5\n"; + +# Test that cloning picks up the correct class for subclasses. +{ + package MD5; + @MD5::ISA = qw(Digest::MD5); +} + +$a = MD5->new; +$a->add("a"); +$b = $a->clone; + +print "not " unless ref($b) eq "MD5" && $b->add("b")->hexdigest eq md5_hex("ab"); +print "ok 6\n"; diff --git a/ext/Digest/MD5/t/files.t b/ext/Digest/MD5/t/files.t index 026342c..f28e0df 100644 --- a/ext/Digest/MD5/t/files.t +++ b/ext/Digest/MD5/t/files.t @@ -20,27 +20,27 @@ use Digest::MD5 qw(md5 md5_hex md5_base64); my $EXPECT; if (ord "A" == 193) { # EBCDIC $EXPECT = <