ruby-1.8.7-p76

ChangeLog

Sun Jan  4 04:49:01 2009  Nobuyoshi Nakada  <nobu@...>

	* win32/win32.c (rb_w32_telldir): just returns loc.

	* win32/win32.c (rb_w32_rewinddir): needs to intialize loc.
	  [ruby-core:18041]

ソースコードの修正内容

Index: win32/win32.c
===================================================================
--- win32/win32.c	(.../v1_8_7_75)	(revision 22266)
+++ win32/win32.c	(.../v1_8_7_76)	(revision 22266)
@@ -1635,15 +1635,7 @@
 long
 rb_w32_telldir(DIR *dirp)
 {
-    long loc = 0; char *p = dirp->curr;
-
-    rb_w32_rewinddir(dirp);
-
-    while (p != dirp->curr) {
-	move_to_next_entry(dirp); loc++;
-    }
-
-    return loc;
+    return dirp->loc;
 }
 
 //
@@ -1668,6 +1660,7 @@
 rb_w32_rewinddir(DIR *dirp)
 {
     dirp->curr = dirp->start;
+    dirp->loc = 0;
 }
 
 //

不具合の内容

rb_w32_telldir calculates the position on each call by repeatedly calling move_to_next_entry.
rb_w32_telldir 関数は、move_to_next_entry 関数を繰り返し呼び出すことで、ディレクトリエントリの位置を計算している。
This increases dirp->loc each time and leads to segfaults in rb_w32_readdir when reading dirp->bits because dirp->loc can be larger than allowed. Simply returning dirp->loc in rb_w32_telldir and zeroing it in rb_w32_rewinddir should suffice.
この処理によって、毎回 dirp->loc の値が増加し、rb_w32_readdir 関数の中で dirp->bits を読み込んだときに SEGV が発生する。これは dirp->loc が許可されているよりも大きな値ことが原因である。

修正の影響や注意点

Windows のみ。
rb_w32_telldir 関数はシンプルに dirp->loc を返すだけに修正し、rb_w32_rewinddir 関数は構造体のメンバを 0 に設定するだけに修正する。
Windows のことはよく分かりません。誰か補足してー。