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 が許可されているよりも大きな値ことが原因である。