Hatena::ブログ(Diary)

Ghosthacks

2009-11-14 (`・ω・´)

lookup が glibc-2.11 な x86_64 環境だとおかしい件

23:44

これは strcpy の挙動が変わったため。

glibc 2.11 で x86_64 用の str* 関数が書き直されたわけ。仕様をちゃんと守って str* 関数を使えばより速く動くらしいのだけど、守らないと期待しているような動作をしてくれないの。

僕が把握している不具合 (正しくは不具合ではないのだけど) は、strcpy 関数の使い方を誤ると思わぬ振る舞いをするというもの。

strcpy 関数というのは以下のようなシグネチャだけど、dest と src のそれぞれの領域が重なってはいけないんだな。だけど、今までの glibc は重なっていてもプログラマが期待した動きをしていたみたい。

char *strcpy(char *dest, const char *src);

glibc 2.11 かつ x86_64 な環境だと dest と src が重なっている場合に妙な振る舞いをする。いや、ちゃんと glibc のコードを追えばきちんとした振る舞いが分かるのかもしれないが。とにかく使う側からしたらおかしな振る舞いにしか見えない。

Momonga Linux の trunk において、この問題で動作が不良になっていたパッケージは、いまのところ make、openoffice.org、fontforge、eblook の 4 つだ。このエントリでは eblook のパッチだけ晒してみよう。

--- eblook-1.6.1/eblook.c.glibc211
+++ eblook-1.6.1/eblook.c
@@ -765,7 +765,7 @@ parse_command_line (command_line, argv)
 	argv[num++] = p;
 	reserved = 1;
       }
-      strcpy (p, p + 1);
+      memmove (p, p + 1, strlen(p + 1) + 1);
       p--;
       in_quote = !in_quote;
       break;
@@ -779,7 +779,7 @@ parse_command_line (command_line, argv)
       break;
 
     case '\\':
-      strcpy (p, p + 1);
+      memmove (p, p + 1, strlen(p + 1) + 1);
     default:
       if (!reserved) {
 	argv[num++] = p;

eblook というのは Emacs 上の辞書引きソフトなのだけど、このパッチがないと正しく辞書を引いてくれない。たとえば、wait を引くと watt の結果が返ってきたりする。

まあ、eblook は本家以外にも配布してる人がいるので、そこでは直っているのかもしれない。

Connection: close