天泣記

2000/09/01

#1

こんなに素直な気持ちで質問したのはひさしぶりな気がする。

#2

sunclock

#3

そーか。リモートで root が使えれば ssh 上で ppp/nat すればいいわけか... たぶん。

2000/09/02

#1

CVS (クライアント)の security に関する Larry Jones の見解

#2

The tcshrc Project Page

#3

invalid character の世界にようこそ、ってやつだな。 うとくないひとはあまりいないと思う。

#4

気が向いたので(どーせそろそろ無意味な蘊蓄になるし)もう少し解説すると、 invalid character というのは、 GNU Emacs 20.3 以上 21 未満に存在する(または問題となる)もので、 それに関する挙動があまりまじめには定義されていないという問題があります。 もちろん、core は吐かないことにはなっていますが、 それも建前だけの話でそのようなバグが残っていたとしても驚くべきことではありません。 したがって、安定した挙動を求めるならば invalid character を使用するべきではありません。 使用した時にどうなるかということがあきらかではないので、 マッチしないのがバグかどうかという判断は非常に困難です。 (なお、もし core を吐いたらそれはあきらかにバグなので bug report しましょう。)

で、invalid character とはいったい何で、どのような時に発生するのか、という話ですが...

GNU Emacs 20.3 以降 21 未満では ストリング(とバッファ)の内容はマルチバイトフラグ(boolean)とバイト列([byte])の直積と1対1に対応します。 ストリングのマルチバイトフラグは (multibyte-string-p str) として観測でき、 バイト列の長さは (length (string-as-unibyte str)) として観測できます。 バイト列の n 番目の要素は (aref (string-as-unibyte str) n) となります。 マルチバイトフラグが真のストリングをマルチバイトストリング、 偽のストリングをユニバイトストリングと呼びます。

ストリング内の各バイトと文字の対応は、マルチバイトフラグの内容によって異なります。 ユニバイトストリング中の各バイトはそれぞれ文字に対応しますが、 マルチバイトストリングの場合には次のような対応となります。

  1. 文字の先頭のバイトが [\000-\177] ならば、 そのバイトだけで一文字である。
  2. 文字の先頭のバイトが [\200-\237] ならば、 それに(最長一致で)引き続く [\240-\377]* も含めて一文字である。
  3. 文字の先頭のバイトが [\240-\377] ならば、 そのバイトだけで一文字である。

上記の 3種類の文字をストリングの先頭から切り出していくことによって、 マルチバイトストリングを文字に分解することができます。

ここで、(2) は、合成文字や非 ASCII 文字に使われますが、 そのような文字とは対応しないバイト列も含んでいます。 (2) のそのような(文字とは対応しない)部分と (3) を invalid character と呼びます。

invalid character が発生する原因はさまざまです。 例えば、(string-as-multibyte str) は マルチバイトフラグだけを真にしたストリングを返すので、 適当なユニバイトストリングを与えれば自由に invalid character を生成できます。 また、マルチバイトストリングをマルチバイトバッファに insert した場合には、 バイト列が無変換で挿入されるため、そのマルチバイトストリングに invalid character が含まれていれば そのマルチバイトバッファにも invalid character が含まれることになるかも知れません。 (ならないかも知れません。invalid character 同士が結合して valid な character になる可能性もあります。) また、マルチバイトバッファでバイト(0 - 255 の整数)を insert すると無変換で 1バイト挿入されるため、 これも invalid character の原因となり得ます。

invalid character が生成される状況では、 ひどく不自然に思える動作をすることがあります。 例えば、(concat (string-as-multibyte "\201") (string-as-multibyte "\241\241\241\241\241\241")) では、 引数のそれぞれ 1文字 と 6文字なのに、連結した結果が(7文字でなく) 1文字になります。 これはストリングの連結の結果、連結した全体で 1文字と解釈されるようなバイト列となるためです。 一般に、このように結合してしまうことを byte combining と呼びます。

invalid character に悩まされないためには、 そもそもそんなものは生成しないというのが基本です。 というわけで、insert で invalid character を作ってしまったというのが敗因ですね。

なお、GNU Emacs 21 や XEmacs ではそもそも invalid character を生成できず、 byte combining もおきないようになっています。

#5

けっきょく、こんなかんじでできる模様。

sudo ipfw add 1000 fwd 127.0.0.1,10000 tcp from this-host to target-host
faucet 10000 --in --out sh -c 'exec ssh dejima hose `getsockname|tail -r` -slave 2>/dev/null'

ぜんぶこの形式で firewall を越えるように設定するのもいいかも知れないな... ssh 以外にも使えるし、ネットワーク単位で設定することもできるし。

#6

netpipes が Debian パッケージになっていないことに驚く。

2000/09/05

#1

invalid character についてですが...

そら set-buffer-multibyte は string-as-multibyte/string-as-unibyte に対応するものですから、 バイト列は変わりません。 バッファに対しての string-make-multibyte/string-make-unibyte に対応するものがないのも事実なんですが。 (こういうのを API の直交性の欠如という。)

コード変換についてはそのまま decode-coding-region すればいいです。 decode-coding-region や encode-coding-region はマルチバイトフラグに影響されません。 つまり、insert-file-contents-literally でファイルを挿入して、 正しい coding system で decode-coding-region を適用すれば正しいマルチバイト表現になります。 したがって、(もしそれがマルチバイトバッファで行なわれるのであれば) decode-coding-region の直前にはほとんど必然的に invalid character を扱うことになります。 これがとある人物(だけではありません)が decode-coding-region/encode-coding-region を嫌う理由であり、 FLIM API がストリングで記事を扱う理由でもあります。

8bit byte が latin-1 などになっていると厄介ですが、 それはそもそもユニバイトからマルチバイトへの変換が起きているのがまずいという立場をとればあまり問題ありません。 (latin-1 以外に設定することも可能だし。)

あと、こちらでは decode-coding-region でちゃんと LATIN SMALL LETTER O WITH DIAERESIS になるし、 detect-coding-region は何かそれなりの値を返すし、 find-charset-region については invalid character に関しての挙動は定義されていないという立場をとれば問題ないです。

ただ detect-coding-region が japanese-shift-jis-unix を返すのは... あぁ、これは拡張領域だからか。

なお、invalid character 関連で 20.3 と 20.7 で違う挙動というのはたくさんあります。 私が関わったものだけでも片手では数え切れません... 2進数でね。

#2

ah-tty: A Helpful TTY

2000/09/07

#1

投稿しないのは 興味を惹かれる話題が出ないから、 などというと怒り出す人もいるかな...

でも、やはり、(emacs 関係でいえば)

などといった話題は少ないしなぁ。

#2

さっさと理解しないと Emacs 21 が出て無意味になるかも知れない...

とはいえまだ pretest も始まってないし、 さらにいえば順調に遅れるだろうし、 十分に時間はあるかも知れないとも思う。

#3

私も指摘ではない 疑問を投稿する ことはめったにありませんねぇ... とっかかりが掴めているならメールやニュースのような二次資料よりも一次資料の方が信用できるし。 とっかかりさえ掴めない問題に当たった場合には投稿することもありますが。

まぁ、結局、書きたくなった時に書けばいいと思うんですが。

#4

個人的には、書きたくなる理由はやはり「自分の知識を深めるついでに他人に伝える」というのが一番大きいかな。 他人が提示した疑問(ないしはそこから派生した疑問)に興味を持って調査して、ついでに返事を書くという。 調べても書かないことも多々あるけれど。

今回 invalid character について書いた件については、 途中で出てきた疑問をいろいろと確認した結果、 Emacs 21 の set-buffer-multibyte/string-as-unibyte/string-as-multibyte の挙動をなんとなく把握できてしまったり、 バグ(かもしれないもの)を 5つも見つけてしまったのでけっこう面白かったですね。 (そのあたりはぜんぜん書かなかったけど。)

#5

情報を収集・共有する という文脈だと... 自分の興味のある情報をかき集めるには、 自分で情報を選別するしかないんじゃないのかなぁ。

自分が注目するものを他人も注目するとは限らないんだし。 ついでにいえば自分が注目したものを全て提示するのは面倒過ぎるし。

各人の興味をクラスタリングして興味を持ちそうな情報をピックアップするというような話が実用化すれば また話は変わってくるんだろうけど。

2000/09/08

#1

Graft: a package management utility

#2

SendIP: commandline tool to send arbitrary IP packets.

2000/09/09

#1

バグレポートをして『なんでそんなことに「ふと気がつく」の? :-)』と問われたらなんと答えるか?

  1. 見張っているから
  2. 天啓により
  3. 探すべきものを探すべき時に探したから
  4. 電波が届いた
  5. バグが俺を呼んでいる
  6. 蟲使いだから

2000/09/10

#1

draft-ukai-mu-protocol-01.txt をよむ。

CR = %x0C だの ESC = %x33 という記述に対し、 これも冗談の一貫なのか単なるミスなのか悩む。

2000/09/11

#1

TimeWarp is a wrapper library that replaces the time() and gettimeofday() functions in any program.

2000/09/12

#1

cvs import における conflict について少し調べる。

#2

Kondara に腕利きが集まりはじめている... ような気がする。

#3

Unicode フォントによるラテン・ギリシア・キリル文字の表示

2000/09/13

#1

ひさしぶりに w3m をバージョンアップしたら Dead Drunk Antenna が一行おきに空行が入って少し悲しい。

2000/09/15

#1

cvs log の結果をパーズしていて、 APEL-CFG などには revision 0.x が存在することに気がつく。

昔(97年頃?)の cvs はそーゆーのを生成したのだろうか?

2000/09/16

#1

cvs で dead な revision の内容を取得することはできるのだろうか?

#2

現実逃避のたまものとして、 cvsmirror がいちおう完成する。

#3

cvssuck という名前にするのではなかったのかと指摘される。 今からでも改名するかな...

2000/09/17

#1

というわけで、cvssuck に改名してみた。

#2

VChacks: Tools for RCS and CVS (cvs_chroot, cvstatus, tag_release, check_release, rcstouch)

tag_release をつかえばリリースする時にタグを付け忘れてもだいじょうぶ... らしい。

#3

さらなる現実逃避: cvs のはなし - オフライン編

2000/09/21

#1

私が『Emacs 使いではない』のは 守岡さんも認める事実です。

2000/09/22

#1

ci の -d は日時を逆行できないのか...

#2

韻を踏んである(何と?)ことをふまえ、CVSsuck と表記することにする。

2000/09/24

#1

時間がかかり過ぎるという声を受け、骨格だけとってくる -s オプションを CVSsuck に実装する。

とってこなかった部分から枝が生えるとその枝については複製不能になるのが問題だが...

2000/09/25

#1

いまさらながらではあるが、 tarball を繰り返し展開するだけでは、Attic へ(から)の移動に対応できないことに気がつく。 しょーがないので別の場所に展開してから mv する。

#2

とーぜん rsync でも同じ問題はあるわけであるが... こちらは --delete があるから対処は楽だな。

2000/09/27

#1

cvsmail: set of utilities to manage the delivery of cvs commit logs via email.

#2

FastCVS: CVS client that will be easy to install & use, and will work with SourceForge.

#3

CVS Web Client: the new name for a combined cvsweb+cvswebedit.

#4

trunk と 1 の違いについて考える。0 や 2 やその他のことも。

うぅむ。trunk だと、prefix をつけるだけでは使い物になりそうにないなぁ。

2000/09/28

#1

cvsadmin: a simple program to administrate users of a CVS repository.


[latest]


田中哲