はじめまして、遠藤侑介と申します。

ruby 1.8.3 にバグらしきものを見つけたので報告致します。
(もし既知でしたらすみません)

IO#read が EOF の後に勝手に 0xFF を追加してしまいます。

$ od -c foo
0000000   f   o   o  \n
0000004
$ ./miniruby -e 'File.open("foo") { |r| p r.read }'
"foo\n\377"

# このため make install すると
# 全てのファイルの末尾に 0xFF が追加されてしまい ruby が実行できません。

原因を探ってみたところ、
関数 read_buffered_data 内で以下のようなコードがあり、

   1023     for (n = 0; n < len && READ_DATA_PENDING(f); ++n) {
   1024         *ptr++ = getc(f);
   1025     }
   1026     return n;

さらに私がコンパイルした環境 (SPARCv9, gcc 3.3.2) では
マクロ READ_DATA_PENDING(fp) が (!feof(fp)) に展開されていました。
(環境: sparc-solaris2.9, gcc 3.3.2)
feof は getc などで EOF に達した後でないと non-zero を返さないので、
ループが一回多く回ってしまい、今回の現象が発生するのだと思います (多分) 。

以下のように修正すると正常に動作する事を確認しました。

--- ruby-1.8.3.old/io.c Tue Sep 27 23:09:50 2005
+++ ruby-1.8.3.new/io.c Tue Sep 27 23:21:54 2005
@@ -153,8 +153,20 @@
 #else
 /* requires systems own version of the ReadDataPending() */
 extern int ReadDataPending();
-#  define READ_DATA_PENDING(fp) (!feof(fp))
+#  define READ_DATA_PENDING(fp) (!pending_p(fp))
 #  define READ_DATA_BUFFERED(fp) 0
+int pending_p(fp)
+    FILE *fp;
+{
+    char c;
+
+    c = getc(fp);
+    if (c == EOF) {
+       return 1;
+    }
+    ungetc(c, fp);
+    return 0;
+}
 #endif
 #ifndef READ_DATA_BUFFERED
 #  define READ_DATA_BUFFERED(fp) READ_DATA_PENDING(fp)

-- 
Yusuke ENDOH <mame / yl.is.s.u-tokyo.ac.jp>