仙石浩明の日記

2006年8月28日

screen 4.0.2 のバグ hatena_b

GNU screen の 最新バージョンである 4.0.2 において、 SJIS な端末で screen を走らせて screen のウィンドウで eucJP を使おうとすると、 1 バイト文字の前に 0x8E が挿入されてしまう。
つまり、 screen のコマンド「encoding eucJP SJIS」 (kanji euc sjis) を実行した場合とか、
あるいは「KJ=SJIS」を指定した端末で「defencoding eucJP」 (defkanji euc) を指定した screen を使うといった場合である。

なぜだろうと思い、ソースを確認すると、encoding.c の 1154 行目あたりが 次のようになっている:

          if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef))
            {
              *statep = c;
              return -1;
            }
          return c | (KANA << 16);

え? これってもしかして 2 バイト文字 (全角文字) 以外は 全て 1 バイトカナ (半角カナ) 扱いにしてしまっている?

screen 4.0.2 は、2004年1月27日に公開されていて (私の知る限り) これが最新版だと思うのだが、 このような単純なバグが 2年以上にわたって放置されているとは信じられないので、 すでにパッチが出回っていて、 開発元にも連絡が行っているのではないかと思う。 ご存じの方はご指摘頂ければ幸いである。 しばらく様子をみて、ご指摘が無いようであれば、 念のため開発元にパッチを送ってみる予定。

言うまでもなく、0x80 未満 (最上位ビットが 0) の文字は、 「KANA」扱いしてはいけないので、 上記コードは以下のようであるべきだ:

          if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef))
            {
              *statep = c;
              return -1;
            }
          if (!(c & 0x80)) return c;
          return c | (KANA << 16);

このような修正を加えることにより、例えば ~/.screenrc

defkanji euc
terminfo xterm KJ=sjis
terminfo kterm KJ=euc
terminfo vt100 AB=\E[4%p1%dm:AF=\E[3%p1%dm:KJ=euc

などと設定して、term=xterm な端末 (term は xterm であるが「シフトJIS」な漢字を表示できる) を使うような場合でも、 漢字を正しく表示できるようになった。

Linux の多くは EUC を標準的な漢字コードとして使っているはずで、 その一方で Windows は SJIS が標準的な漢字コードだったはず (最近は UTF8 の方が多い?) なので、 このような SJIS な端末で EUC な screen を使うケースは 決してレアケースではないと思うのだが、 なぜこのようなバグが放置されていたのかとても不思議である (ちなみに私は Windows 上の TeraTerm を EUC の設定で使っていたため、 このバグに今まで気づかなかった)。

このバグは、端末の漢字コードが SJIS で、かつ screen のウィンドウの漢字コードが SJIS 以外の場合 (つまりコード変換が行なわれる場合) に発現する。 全ての 1 バイトコード (0x00 ~ 0x1F のコントロールコードさえも!) の 前に「0x8E」をつけてくれるので、 screen の detach すらできなくなるという凶悪なものである。
念のため screen 4.0.2 に対する patch の形で修正点を示しておく:

--- encoding.c.org        Mon Sep  8 23:25:23 2003
+++ encoding.c        Mon Aug 28 18:11:57 2006
@@ -1151,6 +1151,7 @@
               *statep = c;
               return -1;
             }
+          if (!(c & 0x80)) return c;
           return c | (KANA << 16);
         }
       t = c;
Filed under: プログラミングと開発環境 — hiroaki_sengoku @ 19:55

3 Comments

  1. screenにバグがあった

    バックグラウンドで走らせたり、コピペする為に二重起動させたりと、何かと使用拒の多いscreenだけど、バグがあることがわかった。詳しくは以下のブログを参照。 screen 4.0.2 のバグ(仙石浩明の日記) 文字コードに関しての事はよくわからないので、漢字の取扱いやその辺の…

    Comment by 弱小ディストリビュータの日記 — 2006年9月8日 @ 00:19

  2. 昔HP-UX 9.xを使ってた頃にsjis->euc変換周りのハンドリングで
    バグがあって、それのパッチを投げたことはあります。
    そのときにはそんな問題はなかったような
    気がするので、いろんなencodingに対応しようとしたあたりで
    エンバグしたんじゃないでしょうか。

    Comment by knok — 2006年9月11日 @ 16:55

  3. screen-devel ML にパッチを送ったところ、
    bug #17842 として登録したよ、という返事が返ってきました。
    https://savannah.gnu.org/bugs/index.php?17842
    直接、この「Savannah」にバグ登録すればよかったのかも?
    https://savannah.gnu.org/bugs/?group=screen&func=additem
    Screen のバグの一覧:
    https://savannah.gnu.org/bugs/?group=screen&func=browse&set=open
    をみると、結構たくさんのバグがそのままになっているようですね。

    Comment by 仙石浩明 — 2006年9月26日 @ 11:28

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.