30 October '2003 - 00:40 | 雑記 大文字小文字
ある人の策略で、bincimap の検索が動かない現象を調べるはめになった。Thunderbird を使う限り、英語なら検索はちゃんと動いてるんだけれど、どうやら wanderlust では動かないらしい。 とりあえず bincimap のソースを読むと、CHARSET は無指定か "US-ASCII" でなきゃいかん、って書いてあった。これはこれで RFC2060 的にはぜんぜん間違った動作じゃない。じゃ、なんで、wanderlust だと英語でも検索できないのか。調べてみると、wanderlust は、CHARSET us-ascii と喋っていることが分かった。
ということは、bincimap は US-ASCII と us-ascii を区別していて、US-ASCII しか受け付けてないってことだ。いいのか、それで。
仕方ないので、RFC2060 を読んでみる。この時点で、完全にハメられてることに気づき始めてはいたけれど、仕方ない。調べてみるしかない。
で、RFC2060 の Formal Syntax には、
<%= pre '
Except as noted otherwise, all alphabetic characters are case-
insensitive. The use of upper or lower case characters to define
token strings is for editorial clarity only. Implementations MUST
accept these strings in a case-insensitive fashion.
' %>
って書いてあるのを発見。発見っていうほどのことでもないんだけれど。ま、そういうわけで、基本的には大文字と小文字の区別をしないのが IMAP のコマンドのようだ。こりゃ、bincimap が間違ってる系かな。
次に、とりあえず、otherwise noted じゃないかどうか、検索コマンドを見てみる。<%= pre '
search ::= "SEARCH" SPACE ["CHARSET" SPACE astring SPACE]
1#search_key
;; [CHARSET] MUST be registered with IANA
'%>
とりあえず、何も注釈がないから、大文字小文字の区別はない。が、しかし。そのルールが [CHARSET] にも適用されるのかどうか、これは別問題だ。だって、IANA が決めてる CHARSET って書いてあるのだから、もし、IANA が大文字小文字の区別をするって書いてたら、区別するのが正解ってことだろうし。
というわけで、IANA の CHARACTER SETS を見てみる。
US-ASCII のところは、<%= pre '
Name: ANSI_X3.4-1968 [RFC1345,KXS2]
MIBenum: 3
Source: ECMA registry
Alias: iso-ir-6
Alias: ANSI_X3.4-1986
Alias: ISO_646.irv:1991
Alias: ASCII
Alias: ISO646-US
Alias: US-ASCII (preferred MIME name)
Alias: us
Alias: IBM367
Alias: cp367
Alias: csASCII
' %>
と書かれていた。
これをみると、どうも charset name は大文字小文字の区別がして書かれているようだ。むむう。
が、しかし、よくよく注意して読んでみると、<%= pre '
The character set names may be up to 40 characters taken from the
printable characters of US-ASCII. However, no distinction is made
between use of upper and lower case letters.
' %>
なんて書かれているのを発見。おぉ、これで決定的だ。区別なしだ。
というわけで、bincimap を直すか。
パッチは、以下。
<%= pre '
--- operator-search.cc.orig Mon Aug 18 11:06:05 2003
+++ operator-search.cc Wed Oct 29 23:16:21 2003
@@ -540,7 +540,10 @@
Mailbox *mailbox = depot.getSelected();
- if (command.getCharSet() != "" && command.getCharSet() != "US-ASCII") {
+ string charset = command.getCharSet();
+ uppercase(charset);
+
+ if (charset != "" && charset != "US-ASCII") {
session.setLastError("[BADCHARSET (\"US-ASCII\")]");
return NO;
}
' %>