diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-11-08 06:43:14 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-11-08 06:43:14 +0000 |
commit | dc98adf839d0d68c4c18647a1db2fb3dc9be8cc4 (patch) | |
tree | 7f6e3c4b45359409bf57526308837f5dbbc45905 /file.c | |
parent | ab827130d3f563535abb7404230f5b5e63bf0946 (diff) |
* process.c (security): always give warning for insecure PATH.
* dir.c (my_getcwd): do not rely on MAXPATHLEN.
* file.c (rb_file_s_readlink): ditto.
* file.c (path_check_1): ditto.
* eval.c (rb_yield_0): should not call rb_f_block_given_p().
* string.c (rb_str_chomp_bang): should terminate string by NUL.
* eval.c (rb_yield_0): better error message.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1816 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'file.c')
-rw-r--r-- | file.c | 78 |
1 files changed, 41 insertions, 37 deletions
@@ -19,6 +19,7 @@ #include "ruby.h" #include "rubyio.h" #include "rubysig.h" +#include "util.h" #include "dln.h" #ifdef HAVE_UNISTD_H @@ -1225,14 +1226,22 @@ rb_file_s_readlink(klass, path) VALUE klass, path; { #ifdef HAVE_READLINK - char buf[MAXPATHLEN]; - int cc; + char *buf; + int size = 100; + int rv; + VALUE v; SafeStringValue(path); - if ((cc = readlink(RSTRING(path)->ptr, buf, MAXPATHLEN)) < 0) - rb_sys_fail(RSTRING(path)->ptr); + buf = xmalloc(size); + if ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) { + size *= 2; + buf = xrealloc(buf, size); + } + if (rv < 0) rb_sys_fail(RSTRING(path)->ptr); + v = rb_tainted_str_new(buf, rv); + free(buf); - return rb_tainted_str_new(buf, cc); + return v; #else rb_notimplement(); return Qnil; /* not reached */ @@ -1297,10 +1306,6 @@ rb_file_s_umask(argc, argv) return INT2FIX(omask); } -#ifndef HAVE_GETCWD -#define getcwd(buf, len) ((void)(len), getwd(buf)) -#endif - #if defined DOSISH #define isdirsep(x) ((x) == '/' || (x) == '\\') #else @@ -2228,29 +2233,31 @@ is_absolute_path(path) static int path_check_1(path) - char *path; + VALUE path; { struct stat st; - char *p = 0; - char *s; + char *p0 = RSTRING(path)->ptr; + char *p, *s; + + if (!is_absolute_path(p0)) { + char *buf = my_getcwd(); + VALUE newpath; - if (!is_absolute_path(path)) { - char buf[MAXPATHLEN+1]; + newpath = rb_str_new2(buf); + free(buf); - if (getcwd(buf, MAXPATHLEN) == 0) return 0; - strncat(buf, "/", MAXPATHLEN); - strncat(buf, path, MAXPATHLEN); - buf[MAXPATHLEN] = '\0'; - return path_check_1(buf); + rb_str_cat2(newpath, "/"); + rb_str_cat2(newpath, p0); + return path_check_1(newpath); } for (;;) { - if (stat(path, &st) == 0 && (st.st_mode & 002)) { + if (stat(p0, &st) == 0 && (st.st_mode & 002)) { if (p) *p = '/'; return 0; } - s = strrdirsep(path); + s = strrdirsep(p0); if (p) *p = '/'; - if (!s || s == path) return 1; + if (!s || s == p0) return 1; p = s; *p = '\0'; } @@ -2260,27 +2267,24 @@ int rb_path_check(path) char *path; { - char *p, *pend; + char *p0, *p, *pend; const char sep = PATH_SEP_CHAR; if (!path) return 1; - p = path; - pend = strchr(path, sep); + pend = path + strlen(path); + p0 = path; + p = strchr(path, sep); + if (!p) p = pend; for (;;) { - int safe; - - if (pend) *pend = '\0'; - safe = path_check_1(p); - if (!safe) { - if (pend) *pend = sep; - return 0; - } - if (!pend) break; - *pend = sep; - p = pend + 1; - pend = strchr(p, sep); + if (!path_check_1(rb_str_new(p0, p - p0))) { + return 0; /* not safe */ + } + if (p0 > pend) break; + p0 = p + 1; + p = strchr(p0, sep); + if (!p) p = pend; } return 1; } |