なかだです。

At Sun, 14 Dec 2003 21:13:00 +0900,
Nobuyoshi-Nakada wrote:
> むしろ、Dir.mkdirとかDir.rmdir自体で対処したほうがよさそうな気も。
> そういえば、Dir.chdirとかDir.chrootは?

対処してみました。file.cとdir.cで同じ処理がいくつかあるので、共
通の関数にしてみました。


* dir.c (check_dirname): check safe string and extraneous trailing
  directory separators.

* file.c: extern rb_path_next, rb_path_skip_prefix,
  rb_path_last_separator, rb_path_end.

* intern.h: prototypes for rb_path_next, rb_path_skip_prefix,
  rb_path_last_separator, rb_path_end.


Index: dir.c =================================================================== RCS file: /cvs/ruby/src/ruby/dir.c,v retrieving revision 1.88 diff -u -2 -p -d -r1.88 dir.c --- dir.c 22 Nov 2003 03:59:17 -0000 1.88 +++ dir.c 15 Dec 2003 00:39:14 -0000 @@ -88,19 +88,8 @@ char *strchr _((char*,char)); #if defined DOSISH #define isdirsep(c) ((c) == '/' || (c) == '\\') -static const char * -find_dirsep(s) - const char *s; -{ - while (*s) { - if (isdirsep(*s)) - return s; - s = CharNext(s); - } - return 0; -} #else #define isdirsep(c) ((c) == '/') -#define find_dirsep(s) strchr(s, '/') #endif +#define find_dirsep(s) rb_path_next(s) static char * @@ -510,4 +499,19 @@ dir_s_getwd(dir) } +static void check_dirname _((volatile VALUE *)); +static void +check_dirname(dir) + volatile VALUE *dir; +{ + char *path, *pend; + + SafeStringValue(*dir); + rb_secure(2); + path = RSTRING(*dir)->ptr; + if (*(path && pend = rb_path_end(rb_path_skip_prefix(path)))) { + *dir = rb_str_new(path, pend - path); + } +} + static VALUE dir_s_chroot(dir, path) @@ -515,6 +519,5 @@ dir_s_chroot(dir, path) { #if defined(HAVE_CHROOT) && !defined(__CHECKER__) - rb_secure(2); - SafeStringValue(path); + check_dirname(&path); if (chroot(RSTRING(path)->ptr) == -1) @@ -544,6 +547,5 @@ dir_s_mkdir(argc, argv, obj) } - SafeStringValue(path); - rb_secure(2); + check_dirname(&path); #ifndef _WIN32 if (mkdir(RSTRING(path)->ptr, mode) == -1) @@ -561,6 +563,5 @@ dir_s_rmdir(obj, dir) VALUE obj, dir; { - SafeStringValue(dir); - rb_secure(2); + check_dirname(&dir); if (rmdir(RSTRING(dir)->ptr) < 0) rb_sys_fail(RSTRING(dir)->ptr); Index: file.c =================================================================== RCS file: /cvs/ruby/src/ruby/file.c,v retrieving revision 1.165 diff -u -2 -p -d -r1.165 file.c --- file.c 11 Dec 2003 02:39:57 -0000 1.165 +++ file.c 15 Dec 2003 00:56:51 -0000 @@ -1460,5 +1460,6 @@ skiproot(path) } -static inline char * +#define nextdirsep rb_path_next +char * nextdirsep(s) const char *s; @@ -1470,9 +1471,10 @@ nextdirsep(s) } -#if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER) -static inline char * +#define skipprefix rb_path_skip_prefix +char * skipprefix(path) const char *path; { +#if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER) #ifdef DOSISH_UNC if (isdirsep(path[0]) && isdirsep(path[1])) { @@ -1487,10 +1489,9 @@ skipprefix(path) #endif return (char *)path; -} -#else -#define skipprefix(path) (path) #endif +} -static char * +#define strrdirsep rb_path_last_separator +char * strrdirsep(path) const char *path; @@ -1511,5 +1512,6 @@ strrdirsep(path) } -static char * +#define chompdirsep rb_path_end +char * chompdirsep(path) const char *path; Index: intern.h =================================================================== RCS file: /cvs/ruby/src/ruby/intern.h,v retrieving revision 1.137 diff -u -2 -p -d -r1.137 intern.h --- intern.h 14 Oct 2003 02:53:53 -0000 1.137 +++ intern.h 15 Dec 2003 00:28:18 -0000 @@ -223,4 +223,8 @@ void rb_file_const _((const char*, VALUE int rb_find_file_ext _((VALUE*, const char* const*)); VALUE rb_find_file _((VALUE)); +char *rb_path_next _((const char *)); +char *rb_path_skip_prefix _((const char *)); +char *rb_path_last_separator _((const char *)); +char *rb_path_end _((const char *)); /* gc.c */ NORETURN(void rb_memerror __((void)));
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦