namazu-ml(avocado)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
uuencode_filter and mailnews_filter
- From: Rei FURUKAWA <furukawa@xxxxxxxxxxxxxxxx>
- Date: Thu, 5 Feb 1998 17:18:07 +0900
- X-ml-name: namazu
- X-mail-count: 00117
古川です。
proto-5 を使って、実際に namazu-ml のログに mknmz してみました。
(-u -h -H を使用)
すると、添付ファイル行が、たくさん単語として登録されてしまいました。
で、原因を探ってみたところ…
(1) uuencode によるもの
(2) multipart によるもの
(1) は、uuencode_filter の中で、
$uunumb = 38;
という行がループの外にあるため、uuencode 行にぶちあたる前に 63 文字の
行があると、
$uunumb = 37 if length($line) == 63;
に引っかかって、値がおかしくなるためでした。
(2) は、この際、multipart に対応してみました。
というわけで、mailnews_filter と uuencode_filter を書き直してみました。
いちおう、私の身近なデータでは試していますが、私の使っていない機能への
影響が無いとは言えないので、そちらでも試してみていただけますでしょうか?
--------------------------- mailnews_filter --------------------------
# Mail/News 用のフィルタ
sub mailnews_filter ($\$\$\$) {
my ($title, $contents, $weighted_str, $header) = @_;
my ($line, $head, $i, @tmp);
local($_);
my ($body, $nontext, @tmp2);
if ($$contents =~ /^\S+:/){
@tmp = split(/\n/, $$contents);
while (defined($_ = shift(@tmp))){
if ($body){
if ($boundary && /^$boundary/){
$body = 0;
}elsif (!$nontext){
push(@tmp2, $_);
}
}else{
if (/^\s/){
$line .= $_;
}else{
if ($line =~ s/^subject:\s*//){
$$title = $line;
# ML 特有の [hogehoge-ML:000] を読み飛ばす。
# のが意図だが、面倒なので、
# 実装上、最初の [...] を読み飛ばす。
$line =~ s/^\[.*?\]//;
# 'Re:' を読み飛ばす。
$line =~ s/\bre: *?//gi;
$$weighted_str .= "\t$TITLEW\t$line\t/$TITLEW\t\n";
&entity_encode($title);
}elsif ($line =~ s/^content-type:\s*//i){
$nontext = ($line !~ /text/i);
if ($line =~ /multipart.*boundary="(.*)"/i){
$boundary = $1;
}
}elsif ($line =~ /^($REMAIN_HEADER):\s+(.*)/i) {
# いくつかのヘッダは保存して検索対象にします
$$weighted_str .= "\t$REMAIN_HEADER_W\t$2\t/$REMAIN_HEADER_W\t\n";
# 一部のヘッダは要約にいれます
$$header .= $line . "\n"
if $line =~ /^($ABSTRACT_HEADER):\s/i;
}
$line = $_;
}
if (($body = /^$/) && !$boundary){
last;
}
}
}
$$contents = join("\n", (@tmp2, @tmp));
}
}
--------------------------- uuencode_filter --------------------------
sub uuencode_filter (\$) {
my ($contents) = @_;
my ($line, @tmp, $uunumb);
my ($uuord, $uuin);
@tmp = split(/\n/, $$contents);
$$contents = "";
while (@tmp) {
$line = shift(@tmp);
$line .= "\n";
# BinHex の読み飛ばし
# 仕様がよく分からないので、最後まで飛ばす
last if $line =~ /^\(This file must be converted with BinHex/; #)
# uuencode の読み飛ばし
# 参考文献 : SunOS 4.1.4 の man 5 uuencode
# FreeBSD 2.2 の uuencode.c
# 偶然マッチしてしまった場合のデメリットを少なくするため
# 本体のフォーマットチェックを行なう
#
# News などでファイルを分割して投稿されているものの場合 begin がない
# ことがあるのでそれを考慮します by S.Takabayashi [v1.0.5]
# 偶然マッチすることはほとんどないとは思いますが…
#
# length は 62 と 63 があるみたい… [v1.0.5]
# もしかしたら他にも違いがあるのかも
#
# 仕様を忠実に表現すると、
# int((ord($line) - ord(' ') + 2) / 3)
# != (length($line) - 2) / 4
# となるが、式を変形して…
# 4 * int(ord($line) / 3) != length($line) + $uunumb;
# FreeBSD の uuencode は、encode に空白も使っている。
# しかし、空白も認めると、一般の行を uuencode 行と誤認する
# 可能性が高くなる。
# 折衷案として、次のケースで認める。
# begin と end の間
# 前の行が uuencode 行と判断されて、ord が前の行と同じ
$uuin = 1, next if $line =~ /^begin [0-7]{3,4} \S+$/;
if ($line =~ /^end$/){
$uuin = 0,next if $uuin;
}else{
# ここで、ord の値は 32-95 の範囲に
$uuord = 32 if ($uuord = ord($line)) == 96;
# uunumb = 38 の行が loop の外に出ていると、
# 一般の行で 63 文字の行があったら誤動作してしまう
$uunumb = (length($line)==63)? 37: 38;
if ((32 <= $uuord && $uuord < 96) &&
length($line) <= 63 &&
(4 * int($uuord / 3) == length($line) + $uunumb)){
if ($uuin == 1 || $uuin == $uuord){
next if $line =~ /^[\x20-\x60]/;
}else{
$uuin = $uuord, next if $line =~ /^[\x21-\x60]/;
}
}
}
$uuin = 0;
$$contents .= $line;
}
}
------------------------------ ここまで ------------------------------
明日から、しばらくメールが読めないと思いますが、今後ともよろしくお願い
致します。
--
ヤマハ(株)ピアノプレーヤ設計課
古川 令
furukawa@xxxxxxxxxxxxxxxx