GetLastRecvMailFromの不具合No.42785
Roka さん 12/05/31 14:56
 
メールヘッダーのFromがMIME iso-2022-jp base64でエンコードされている場合、
GetLastRecvMailFromでデコードされていないようです。
メール本体では正しく表示されていました。

[ ]
RE:42785 GetLastRecvMailFromの不具合No.42786
秀まるお2 さん 12/05/31 18:20
 
 こちらで簡単にテストした限りでは大丈夫そうでした。

 From:ヘッダの中の日本語の文字列は、大抵のメールでは、iso-2022-jp
base64でエンコードされてます。秀丸メールで送信したメールもそうなっていま
す。

 例えば、今こちらで、

From: =?iso-2022-jp?B?GyRCQEZGIz0oSVcbKEI=?= <xxxxx@xxxxxx.or.jp>

 みたいなメールを受信して、例えば以下のマクロを実行したら、こちらでは正
しく「斉藤秀夫 <xxxxx@xxxxxx.or.jp>」のように表示されました。

 マクロの例:

    loaddll "tkinfo.dll";
    #c = dllfunc("RecvMailCountShow");
    #i = 0;
    while( #i < #c ) {
        $from = dllfuncstr("GetLastRecvMailFrom", #i);
        $subject = dllfuncstr("GetLastRecvMailSubject", #i);
        message $from + " / " + $subject;
        #i = #i + 1;
    }

 何かダメなメールの例とかダメなマクロの例とかがあれば教えて欲しいです。

[ ]
RE:42786 GetLastRecvMailFromの不具合No.42789
Roka さん 12/06/01 11:07
 
すみません、こちらの確認不足でした。こちらでも他のMIME iso-2022-jp base64の
メールはちゃんとデコードされていました。
不具合の出たメールを改めて調べてみたところ

From: =?iso-2022-jp?B?GyRCQEZGIz0oSVcbKEI=?=【改行】
【タブ】<xxxxx@xxxxxx.or.jp>

のような状態でした。

[ ]
RE:42789 GetLastRecvMailFromの不具合No.42790
秀まるお2 さん 12/06/01 16:03
 
 その条件でもテストしてみたんですが、いまいち現象が確認出来ませんでした。

 ソースコードも見直してみたんですが、GetLastRecvMailFromとかで返す用の
データは、たしかにデコードした後のメールの情報をセットしているようです。
なので、もしそれが「=?ISO-2022-JP...」のようになってしまうとしたら、受信
フォルダとかに出てくるメールもそういう表示になってないとおかしいはずだと
思います。

 ってことでちょっと分からなくなりました。

 実は、GetLastRecvMailFrom/GetLastRecvMailSubjectの関数は、以前から1つ
問題がありました。日本語やutf-8のメールはうまく処理するんですが、欧文と
か中国語のメールはうまく処理出来てませんでした。それのせいでおかしいって
ことはありますけども、今回のケースはたしかに日本語のメールなのですよね。

 他の可能性としてですが…

 もしかして、定期受信の動作を「リモートメールの一覧取得」にしている時に、
リモートメール一覧を取得した結果に対してのGetLastRecvMailFromだとしたら、
リモートメール一覧の場合はメール本文まで正確にデコードした訳じゃないがた
めに、文字コードがはっきり判別出来ないことがあって、それのせいでおかしく
なってる可能性はあるにはあります。

 ですが、別にそういう話(定期受信でリモートメール一覧取得を実行してる)
では無いですよね。

 他には…。すみませんがちょっと分かりません。

 とりあえず簡単に、再現テストをする用のマクロを作ったので、それだけ掲載
してみます。それでテストした結果再現するかどうかだけでも教えていただけま
すでしょうか。それで再現しないとしたら、例えばどういうケースで起きるのか
何かヒントが欲しい所です。

■テスト用のマクロ:

 受信ログの存在してそうな、何か適当な最近受信したメールを1つ選択して実
行する用になってます。


    loaddll "tkinfo.dll";
    question "テストメールを送信してからテストしますか?\n\n"
            + "(テストメールは現在選択してるメールの受信ログを加工して"
            + "「そのまま転送」で送ります。)";
    if( result == yes ) {
        #n = dllfunc("LoadAccountProp", dllfuncstr("CurrentAccount"));
        $myemail = dllfuncstr("GetAccountProp", "szEmail");

        #n = dllfunc("MakeResentForward", $myemail, "open", "log");
        if( #n == 0 ) {
            message "そのまま転送コマンドに失敗しました。";
            endmacro;
        }
        while( dllfunc("DeleteHeader", "To") ) {
            //
        }
        while( dllfunc("DeleteHeader", "Cc") ) {
            //
        }
        #n = dllfunc("SetHeader", "From",
           "=?iso-2022-jp?B?GyRCQEZGIz0oSVcbKEI=?=\n\t<xxxxx@xxxxxx.or.jp>");
        #n = dllfunc("SetHeader", "Subject", "testmail");
        #n = dllfunc("SetHeader", "To", "testmail");

        gofiletop;
        beginsel;
        gofileend;
        delete;
        insert "testmail\n";
        #n = dllfunc("SendNow");
        if( #n == 0 ) {
            message "送信に失敗しました。";
            endmacro;
        }
        #handle = hidemaruhandle(0);
        #n = dllfunc("SetMainWndTop");
        closehidemaruforced #handle;

Loop:
        #n = dllfunc("SetAutoPushTimer", 10, "" );
        message "メールが届くまで待機しています。(10秒)";
        #n = dllfunc("StopAutoPushTimer");
        #n = dllfunc("Receive");
        #c = dllfunc("RecvMailCountShow");
        if( #c == 0 ) {
            goto Loop;
        }
    }
    #c = dllfunc("RecvMailCountShow");
    #i = 0;
    while( #i < #c ) {
        $from = dllfuncstr("GetLastRecvMailFrom", #i);
        $subject = dllfuncstr("GetLastRecvMailSubject", #i);
        message $from + " / " + $subject;
        #i = #i + 1;
    }

[ ]
RE:42790 GetLastRecvMailFromの不具合No.42791
Roka さん 12/06/02 23:21
 
> その条件でもテストしてみたんですが、いまいち現象が確認出来ませんでした。
>

お手数おかけしています。メール固有の問題なのでしょうか。

> ソースコードも見直してみたんですが、GetLastRecvMailFromとかで返す用の
>データは、たしかにデコードした後のメールの情報をセットしているようです。
>なので、もしそれが「=?ISO-2022-JP...」のようになってしまうとしたら、受信
>フォルダとかに出てくるメールもそういう表示になってないとおかしいはずだと
>思います。
>
> ってことでちょっと分からなくなりました。
>
> 実は、GetLastRecvMailFrom/GetLastRecvMailSubjectの関数は、以前から1つ
>問題がありました。日本語やutf-8のメールはうまく処理するんですが、欧文と
>か中国語のメールはうまく処理出来てませんでした。それのせいでおかしいって
>ことはありますけども、今回のケースはたしかに日本語のメールなのですよね。
>

はい、日本語のメールです。

> 他の可能性としてですが…
>
> もしかして、定期受信の動作を「リモートメールの一覧取得」にしている時に、
>リモートメール一覧を取得した結果に対してのGetLastRecvMailFromだとしたら、
>リモートメール一覧の場合はメール本文まで正確にデコードした訳じゃないがた
>めに、文字コードがはっきり判別出来ないことがあって、それのせいでおかしく
>なってる可能性はあるにはあります。

リモートメールの取得に対して実行しています。ただ取得行数は999行で、メール自
体は20行程度の文字列のみのメールでした。

>
> ですが、別にそういう話(定期受信でリモートメール一覧取得を実行してる)
>では無いですよね。
>
> 他には…。すみませんがちょっと分かりません。
>

今までGetLastRecvMailFromの表示内容がおかしかった覚えはないので、何か特殊な
例かもしれません。
ただ気になるのはGetLastRecvMailFromで表示がおかしかった直後にリモートメール
を実行した時の表示は
正しかったのでGetLastRecvMailFromに何か原因があるのではと思った次第です。
また何かわかりましたらお知らせします。

[ ]
RE:42791 GetLastRecvMailFromの不具合No.42796
Roka さん 12/06/04 17:09
 
一つ気になる点があったのでお知らせします。
送られてきたメールを調べてみたところ
From: =?iso-2022-jp?B?【以下省略】
Subject: =?UTF-8?B?【以下省略】
Content-Type: text/plain; charset="UTF-8"
となっており文字コードが混ざっているようです。

[ ]
RE:42796 GetLastRecvMailFromの不具合No.42800
秀まるお2 さん 12/06/04 18:03
 
 そういうメールを意図的に作成してテストしたら、「=?iso-2022-jp?b?...」
のようにはなりませんでしたが、代わりに、utf-8文字コードのままでShift-JIS
に変換されない文字列が出てきてしまうようでした。

 リモートメール一覧の場合はちょっと処理が違ってるのでこういうこともあり
えるのかなぁと思っていましたが、たしかにダメなケースがあるようです。

 原因や対策を調べてみます。

ちなみにテストマクロ:

    loaddll "tkinfo.dll";
    question "テストメールを送信してからテストしますか?\n\n"
            + "(テストメールは現在選択してるメールの受信ログを加工して"
            + "「そのまま転送」で送ります。)";
    if( result == yes ) {
        #n = dllfunc("LoadAccountProp", dllfuncstr("CurrentAccount"));
        $myemail = dllfuncstr("GetAccountProp", "szEmail");

        #n = dllfunc("MakeResentForward", $myemail, "open", "log");
        if( #n == 0 ) {
            message "そのまま転送コマンドに失敗しました。";
            endmacro;
        }
        while( dllfunc("DeleteHeader", "To") ) {
            //
        }
        while( dllfunc("DeleteHeader", "Cc") ) {
            //
        }
        #n = dllfunc("SetHeader", "From",
           "=?iso-2022-jp?B?GyRCQEZGIz0oSVcbKEI=?=\n\t<xxxxx@xxxxxx.or.jp>");
        #n = dllfunc("SetHeader", "Subject",
           "=?utf-8?B?44OG44K544OI?=");
        #n = dllfunc("SetHeader", "To", "testmail");

        gofiletop;
        beginsel;
        gofileend;
        delete;
        insert "testmail\n";
        #n = dllfunc("SendNow");
        if( #n == 0 ) {
            message "送信に失敗しました。";
            endmacro;
        }
        #handle = hidemaruhandle(0);
        #n = dllfunc("SetMainWndTop");
        closehidemaruforced #handle;

Loop:
        #n = dllfunc("SetAutoPushTimer", 10, "" );
        message "メールが届くまで待機しています。(10秒)";
        #n = dllfunc("StopAutoPushTimer");
        #n = dllfunc("TransmitCustom", dllfuncstr("CurrentAccount") + ":L");
        #c = dllfunc("RemoteMailHotCount");
        if( #c == 0 ) {
            goto Loop;
        }
    }
    #c = dllfunc("RemoteMailHotCount");
    #i = 0;
    while( #i < #c ) {
        $from = dllfuncstr("GetLastRecvMailFrom", #i);
        $subject = dllfuncstr("GetLastRecvMailSubject", #i);
        message $from + " / " + $subject;
        #i = #i + 1;
    }

[ ]