DateTime::Format::Mailがシグニチャのミスマッチでインストールできない問題の調査

Plaggerな世界に0.1歩ほど足を踏み入れるでDateTime::Format::Mailがインストールできなかった件の続き。タイトルながいな、また。

DateTime::Format::Mailをインストールしようとするとシグニチャと実際のファイルのハッシュ値が一致しなくてエラーが発生し、インストールできない。どうもt/sample_datesというファイルのハッシュ値がよろしくないらしい。ログを抜粋すると以下のような感じ。

--- SIGNATURE   2003-10-22 00:22:33.000000000 +0900
+++ -   2006-05-31 19:28:17.000000000 +0900

~中略~

-SHA1 ebb870712a24d7eb425c63ff8a438b7f1eddabb2 t/sample_dates
+SHA1 7db435556975438402ca1156346325dcfd2f4dda t/sample_dates

~中略~

==> MISMATCHED content between SIGNATURE and distribution files! <==

期待されるハッシュ値が-SHA1からはじまる行に表示されていて、計算されたハッシュ値が+SHA1からはじまる行に表示されている。

Module::Signatureのソース読んだりしてみるうちに、この現象を再現できた。再現用コードは以下。Module::Signaute 0.54でないと再現しない。理由は後述。

use strict;
use Digest::SHA;

my $infile = $ARGV[0];
# DateTime-Format-MailのSIGNATUREはSHA1
my $sha = Digest::SHA->new(1);

# 単純にハッシュを計算
open SD, $infile;
$sha->addfile(*SD);
my $hd = $sha->hexdigest;

print 'normal:  ';
print "$hd\n";


# リセット
$sha->reset;
close SD;


# Module-Signatureで取られている方法で計算
open SD, $infile;

# Module-Signature-0.54では非バイナリファイルに以下の処理が施される
binmode(SD, ':crlf');

$sha->addfile(*SD);
$hd = $sha->hexdigest;

print 'binmode: ';
print "$hd\n";

そして、実行結果は以下。

$ perl sha.pl t/sample_dates 
normal:  ebb870712a24d7eb425c63ff8a438b7f1eddabb2
binmode: 7db435556975438402ca1156346325dcfd2f4dda

インストール時のエラーメッセージと同様のハッシュ値が得られた。

Module::Signatureで非バイナリファイルのハッシュを計算するときに実行されるbimode(SD, ':crlf')が悪さをしているようだ。このコードはModule::Signatureの最新バージョンである0.54から現れるコードなので、Module::Signatureが最新で無い場合はDateTime::Format::Mailはエラーなくインストールされると考えられる。

しかし、疑問であるのは、t/sample_dates意外のファイルでこのスクリプトを実行しても同じハッシュ値が得られるということ。このt/sample_datesにはなにかあるようだ。ていうかどっかに\r\nが紛れ込んでんじゃね?ということで、以下を試してみる。すると、

$ cat t/sample_dates | perl -n -e 'print "$.: $_" if /\r\n/'
10464: Mon 05 Mar 2001 04:30:10 +1100

10464行目になんかいたぞー!これはもう意図的に\r\nをふくんでいるのかどうかわかんないんだけど、Module::SignatureとDateTime::Format::Mailの不幸な組み合わせと言うか。しかし、既存のものでエラー出してんだからModule::Signatureは修正必要なんではと思ったり。

なにはともあれ、t/sample_datesというファイルが改ざんされているようことはなさそうなので、DateTime::Format::Mailもforce installかな。