🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: fj.mail
Article #152

Anti MIME encoding header(Re: RFC 2822 のプロトコル上の欠陥)

#152
From: Masanori HATA
Date: Thu, 29 Dec 2005 11:43
151 lines
7028 bytes
畑です。その後(:-D)です。

# フォロー内容によってフォロー先をお絞り下さい。

Masanori HATA wrote:
> MIME (RFC 2047) というよりも RFC 2822 のヘッダの折り返し(folding)ルー
> ル自体の欠陥のせいみたいですね。
>
> RFC 2822 の WSP として定義されているものを SP と HTAB で使い分けるように
> 修正すれば従来の(欧語中心に設計された)仕様に大きな影響を与えることな
> く、日本語(中国語・韓国語も同様ですが)にとっての欠陥を解消できるように
> 思えます。
>
> HTAB を FWS として使用した場合は、折り返し解除(unfolding)時に削除され
> る WSP として扱うというルールにすればいいと思うわけです。
(中略)
> こういうことにすれば、8bit システム下では、MIME エンコードヘッダは不要に
> なり、quoted-string さえ必要なときに用いれば、生 UTF-8 の題名
> (unstructured)やアドレス(structured)の表示名(display-name)でも可能
> になりますね。

──なんてことを考えたりしていましたが、もう一つ別なやり方を考えました。

それは、長い文字列を折り返するために、強制的に空白文字を挿入する場合、空白
文字の後に続けて、制御文字のBS(バックスペース:ASCIIコード8)をペアにする
という方法です。これも、メールリーダ側でBSの解釈についてコンセンサスを得ら
れていなければ、意味はありませんので、単なる提案にすぎませんが。

そんなわけで、unstructured ヘッダ(例:題名ヘッダ)に関して、RFC 2047 の
MIME 符号化ヘッダ方式を無視して、MIME 符号化しない、素の UTF-8 の文字列を
RFC 2822 の制限文字数 78 バイト以内に折返しする方式を採用してみました。や
っているのは、多バイト長文字の場合は、途中で強制改行がされることのないよう
に注意している程度です。

下にプロトタイプを載せておきます。

# 再帰的表現ですっきり書けたつもりです。;-)
# ついでに日本語使いまくり。

MIME 符号化する方式のものはまた別途作る予定です。

-- 
Masanori HATA



#!/usr/local/bin/perl -w
use 5.008;
use strict;
use warnings;
use utf8;

use Carp;

# 定数の宣言
my $行長 = 78;
my $短語 = $行長 - 1;
my $長語 = $短語 + 1;
my $改行 = "\x0D\x0A";
my $空白文字種 = "\x20\x09";
my $第八位文字種 = "\x80-\xFF";
my $強制改行時空白 = "\x20\x08";

# パッケージ内グローバル変数の宣言
my($処理済, $未処理);

sub 短いASCII語 ($) {
    my $処理対象 = $_[0];

    $処理済 =~ m/($改行|^)([^$改行]*)$/;
    my $最後尾 = $2;

    if (length($処理対象) <= $行長 - length($最後尾)) {
        $処理済 .= $処理対象;
    }
    else {
        $処理済 .= $改行 . $処理対象;
    }
}

sub 長いASCII語 ($) {
    my $処理対象 = $_[0];

    $処理済 =~ m/($改行|^)([^$改行]*)$/;
    my $最後尾 = $2;

    my $余地 = $行長 - length($最後尾);

    if ($余地 and $余地 >= length($処理対象)) {
        $処理済 .= $処理対象;
    }
    elsif ($余地) {
        $処理済 .= substr($処理対象, 0, $余地);
        # 再帰
        &長いASCII語( substr($処理対象, $余地) );
    }
    else {
        $処理済 .= $改行 . $強制改行時空白;
        # 再帰
        &長いASCII語($処理対象);
    }
}

sub 長い第八位文字含有語 ($) {
    utf8::decode(my $処理対象 = $_[0]);
    utf8::encode(my $一文字 = substr($処理対象, 0, 1));

    $処理済 =~ m/($改行|^)([^$改行]*)$/;
    my $最後尾 = $2;

    if (length($一文字) <= $行長 - length($最後尾)) {
        $処理済 .= $一文字;
    }
    else {
        $処理済 .= $改行 . $強制改行時空白 . $一文字;
    }

    utf8::encode(my $残り = substr($処理対象, 1));
    # 再帰
    &長い第八位文字含有語($残り) if $残り;
}

sub 折返す ($$) {
    $処理済 = $_[0] . ':';
    utf8::encode($未処理 = "\x20" . $_[1]);

    while ($未処理) {
        if ($未処理 =~ s/^[$空白文字種][^$空白文字種]{1,$短語}(?=[$空白文字種]|$)//) {
            短いASCII語($&);
        }
        elsif ($未処理 =~ s/^[$空白文字種]//) {
            短いASCII語($&);
        }
        elsif ($未処理 =~ s/^[^$空白文字種^$第八位文字種]{$長語,}(?=[$空白文字種]|$)//) {
            長いASCII語($&);
        }
        elsif ($未処理 =~ s/^[^$空白文字種]{$長語,}(?=[$空白文字種]|$)//) {
            長い第八位文字含有語($&);
        }
        else {
            carp 'unsupposed regex error: ' . $未処理 . ';';
        }
    }
}


# 以下、使用例
my $領域名 = 'Subject';
my $領域内容 = 'これは筆です。これは筆です。これは筆です。これは筆です。';
折返す($領域名, $領域内容);
print $処理済;
Technical Details
Message-ID: <dp0i4q$d3k$1@caraway.media.kyoto-u.ac.jp>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newscon06.news.prodigy.com!newscon02.news.prodigy.com!prodigy.net!newsfeed.media.kyoto-u.ac.jp!msi.co.jp!news.media.kyoto-u.ac.jp!not-for-mail
References: <dms3p3$iks$1@caraway.media.kyoto-u.ac.jp> <3992513news.pl@rananim.ie.u-ryukyu.ac.jp> <dmtrle$adg$1@caraway.media.kyoto-u.ac.jp> <3992518news.pl@rananim.ie.u-ryukyu.ac.jp> <dn0g4h$rgh$1@caraway.media.kyoto-u.ac.jp> <3992522news.pl@rananim.ie.u-ryukyu.ac.jp> <dn3oc8$366$1@caraway.media.kyoto-u.ac.jp> <3992529news.pl@rananim.ie.u-ryukyu.ac.jp> <dndm98$o0u$1@caraway.media.kyoto-u.ac.jp>

Show Full Headers
Complete Article Headers
X-Google-Thread: 106028,a7d5d47968170444
X-Google-Thread: 100bbf,ff538ee3ae7d2cc1
X-Google-Thread: f9898,ba1deb2ed025dad8
X-Google-Attributes: gid106028,gid100bbf,gidf9898,public
X-Google-Language: Japanese,JIS
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newscon06.news.prodigy.com!newscon02.news.prodigy.com!prodigy.net!newsfeed.media.kyoto-u.ac.jp!msi.co.jp!news.media.kyoto-u.ac.jp!not-for-mail
From: Masanori HATA <hata@iname.com>
Newsgroups: fj.mail,fj.net.mime,fj.comp.lang.perl
Subject: Anti MIME encoding header(Re: RFC 2822 のプロトコル上の欠陥)
Date: Thu, 29 Dec 2005 20:43:21 +0900
Organization: (an individual)
Lines: 151
Sender: hata@iname.com
Message-ID: <dp0i4q$d3k$1@caraway.media.kyoto-u.ac.jp>
References: <dms3p3$iks$1@caraway.media.kyoto-u.ac.jp> <3992513news.pl@rananim.ie.u-ryukyu.ac.jp>          <dmtrle$adg$1@caraway.media.kyoto-u.ac.jp> <3992518news.pl@rananim.ie.u-ryukyu.ac.jp> <dn0g4h$rgh$1@caraway.media.kyoto-u.ac.jp>    <3992522news.pl@rananim.ie.u-ryukyu.ac.jp> <dn3oc8$366$1@caraway.media.kyoto-u.ac.jp> <3992529news.pl@rananim.ie.u-ryukyu.ac.jp> <dndm98$o0u$1@caraway.media.kyoto-u.ac.jp>
NNTP-Posting-Host: pl1528.nas924.soka.nttpc.ne.jp
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit
X-Trace: caraway.media.kyoto-u.ac.jp 1135856602 13428 219.102.121.248 (29 Dec 2005 11:43:22 GMT)
X-Complaints-To: news@news.media.kyoto-u.ac.jp
NNTP-Posting-Date: Thu, 29 Dec 2005 11:43:22 +0000 (UTC)
User-Agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)
X-Accept-Language: ja, en-us, en
In-Reply-To: <dndm98$o0u$1@caraway.media.kyoto-u.ac.jp>