ruby-changes:12153
From: nobu <ko1@a...>
Date: Tue, 23 Jun 2009 16:05:35 +0900 (JST)
Subject: [ruby-changes:12153] Ruby:r23828 (trunk): * file.c (rb_find_file_ext, rb_find_file): no needs to expand
nobu 2009-06-23 16:05:04 +0900 (Tue, 23 Jun 2009) New Revision: 23828 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=23828 Log: * file.c (rb_find_file_ext, rb_find_file): no needs to expand paths with tilde twice. * load.c (rb_f_load): load the given path directly if not found in load_path. * load.c (search_required): search file in specified safe level. * load.c (rb_require_safe): path to load is already searched in search_required(). Modified files: trunk/ChangeLog trunk/file.c trunk/include/ruby/intern.h trunk/load.c Index: include/ruby/intern.h =================================================================== --- include/ruby/intern.h (revision 23827) +++ include/ruby/intern.h (revision 23828) @@ -345,6 +345,9 @@ VALUE rb_file_s_absolute_path(int, VALUE *); VALUE rb_file_absolute_path(VALUE, VALUE); void rb_file_const(const char*, VALUE); +int rb_file_load_ok(const char *); +int rb_find_file_ext_safe(VALUE*, const char* const*, int); +VALUE rb_find_file_safe(VALUE, int); int rb_find_file_ext(VALUE*, const char* const*); VALUE rb_find_file(VALUE); char *rb_path_next(const char *); Index: ChangeLog =================================================================== --- ChangeLog (revision 23827) +++ ChangeLog (revision 23828) @@ -1,3 +1,16 @@ +Tue Jun 23 16:04:59 2009 Nobuyoshi Nakada <nobu@r...> + + * file.c (rb_find_file_ext, rb_find_file): no needs to expand + paths with tilde twice. + + * load.c (rb_f_load): load the given path directly if not found in + load_path. + + * load.c (search_required): search file in specified safe level. + + * load.c (rb_require_safe): path to load is already searched in + search_required(). + Tue Jun 23 12:43:56 2009 Nobuyoshi Nakada <nobu@r...> * configure.in: remove PACKAGE_* macros generated by autotools. Index: load.c =================================================================== --- load.c (revision 23827) +++ load.c (revision 23828) @@ -252,10 +252,9 @@ NORETURN(static void load_failed(VALUE)); -void -rb_load(VALUE fname, int wrap) +static void +rb_load_internal(VALUE fname, int wrap) { - VALUE tmp; int state; rb_thread_t *th = GET_THREAD(); volatile VALUE wrapper = th->top_wrapper; @@ -266,14 +265,6 @@ rb_thread_t *volatile th0 = th; #endif - FilePathValue(fname); - fname = rb_str_new4(fname); - tmp = rb_find_file(fname); - if (!tmp) { - load_failed(fname); - } - RB_GC_GUARD(fname) = rb_str_new4(tmp); - th->errinfo = Qnil; /* ensure */ if (!wrap) { @@ -325,6 +316,14 @@ } void +rb_load(VALUE fname, int wrap) +{ + VALUE tmp = rb_find_file(FilePathValue(fname)); + if (!tmp) load_failed(fname); + rb_load_internal(tmp, wrap); +} + +void rb_load_protect(VALUE fname, int wrap, int *state) { int status; @@ -355,10 +354,16 @@ static VALUE rb_f_load(int argc, VALUE *argv) { - VALUE fname, wrap; + VALUE fname, wrap, path; rb_scan_args(argc, argv, "11", &fname, &wrap); - rb_load(fname, RTEST(wrap)); + path = rb_find_file(FilePathValue(fname)); + if (!path) { + if (!rb_file_load_ok(RSTRING_PTR(fname))) + load_failed(fname); + path = fname; + } + rb_load_internal(path, RTEST(wrap)); return Qtrue; } @@ -435,7 +440,7 @@ } static int -search_required(VALUE fname, volatile VALUE *path) +search_required(VALUE fname, volatile VALUE *path, int safe_level) { VALUE tmp; char *ext, *ftptr; @@ -450,7 +455,7 @@ if (loading) *path = rb_str_new2(loading); return 'r'; } - if ((tmp = rb_find_file(fname)) != 0) { + if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, Qtrue, Qtrue, &loading) || loading) *path = tmp; @@ -466,7 +471,7 @@ tmp = rb_str_new(RSTRING_PTR(fname), ext - RSTRING_PTR(fname)); #ifdef DLEXT2 OBJ_FREEZE(tmp); - if (rb_find_file_ext(&tmp, loadable_ext + 1)) { + if (rb_find_file_ext_safe(&tmp, loadable_ext + 1, safe_level)) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading) *path = tmp; @@ -475,7 +480,7 @@ #else rb_str_cat2(tmp, DLEXT); OBJ_FREEZE(tmp); - if ((tmp = rb_find_file(tmp)) != 0) { + if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading) *path = tmp; @@ -488,7 +493,7 @@ if (loading) *path = rb_str_new2(loading); return 's'; } - if ((tmp = rb_find_file(fname)) != 0) { + if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) { ext = strrchr(ftptr = RSTRING_PTR(tmp), '.'); if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading) *path = tmp; @@ -501,8 +506,7 @@ return 'r'; } tmp = fname; - type = rb_find_file_ext(&tmp, loadable_ext); - tmp = rb_file_expand_path(tmp, Qnil); + type = rb_find_file_ext_safe(&tmp, loadable_ext, safe_level); switch (type) { case 0: if (ft) @@ -567,19 +571,15 @@ rb_set_safe_level_force(safe); FilePathValue(fname); rb_set_safe_level_force(0); - found = search_required(fname, &path); + found = search_required(fname, &path, safe); if (found) { if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) { result = Qfalse; } else { - if (safe > 0 && OBJ_TAINTED(path)) { - rb_raise(rb_eSecurityError, "cannot load from insecure path - %s", - RSTRING_PTR(path)); - } switch (found) { case 'r': - rb_load(path, 0); + rb_load_internal(path, 0); break; case 's': Index: file.c =================================================================== --- file.c (revision 23827) +++ file.c (revision 23828) @@ -4590,6 +4590,12 @@ return ret; } +int +rb_file_load_ok(const char *path) +{ + return file_load_ok(path); +} + static int is_explicit_relative(const char *path) { @@ -4600,33 +4606,50 @@ VALUE rb_get_load_path(void); +static VALUE +copy_path_class(VALUE path, VALUE orig) +{ + RBASIC(path)->klass = rb_obj_class(orig); + OBJ_FREEZE(path); + return path; +} + int rb_find_file_ext(VALUE *filep, const char *const *ext) { - const char *f = RSTRING_PTR(*filep); - VALUE fname, load_path, tmp; + return rb_find_file_ext_safe(filep, ext, rb_safe_level()); +} + +int +rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level) +{ + const char *f = StringValueCStr(*filep); + VALUE fname = *filep, load_path, tmp; long i, j, fnlen; + int expanded = 0; if (!ext[0]) return 0; if (f[0] == '~') { fname = rb_file_expand_path(*filep, Qnil); - if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) { + if (safe_level >= 1 && OBJ_TAINTED(fname)) { rb_raise(rb_eSecurityError, "loading from unsafe file %s", f); } - OBJ_FREEZE(fname); - f = StringValueCStr(fname); + f = RSTRING_PTR(fname); *filep = fname; + expanded = 1; } - if (is_absolute_path(f) || is_explicit_relative(f)) { - fname = rb_file_expand_path(*filep, Qnil); + if (expanded || is_absolute_path(f) || is_explicit_relative(f)) { + if (safe_level >= 1 && !fpath_check(f)) { + rb_raise(rb_eSecurityError, "loading from unsafe path %s", f); + } + if (!expanded) fname = rb_file_expand_path(fname, Qnil); fnlen = RSTRING_LEN(fname); for (i=0; ext[i]; i++) { rb_str_cat2(fname, ext[i]); - if (file_load_ok(StringValueCStr(fname))) { - OBJ_FREEZE(fname); - *filep = fname; + if (file_load_ok(RSTRING_PTR(fname))) { + *filep = copy_path_class(fname, *filep); return (int)(i+1); } rb_str_set_len(fname, fnlen); @@ -4634,7 +4657,11 @@ return 0; } - load_path = rb_get_load_path(); + if (safe_level >= 4) { + rb_raise(rb_eSecurityError, "loading from non-absolute path %s", f); + } + + RB_GC_GUARD(load_path) = rb_get_load_path(); if (!load_path) return 0; fname = rb_str_dup(*filep); @@ -4650,9 +4677,7 @@ if (RSTRING_LEN(str) == 0) continue; file_expand_path(fname, str, 0, tmp); if (file_load_ok(RSTRING_PTR(tmp))) { - RBASIC(tmp)->klass = rb_obj_class(*filep); - OBJ_FREEZE(tmp); - *filep = tmp; + *filep = copy_path_class(tmp, *filep); return (int)(j+1); } FL_UNSET(tmp, FL_TAINT | FL_UNTRUSTED); @@ -4666,28 +4691,37 @@ VALUE rb_find_file(VALUE path) { + return rb_find_file_safe(path, rb_safe_level()); +} + +VALUE +rb_find_file_safe(VALUE path, int safe_level) +{ VALUE tmp, load_path; const char *f = StringValueCStr(path); + int expanded = 0; if (f[0] == '~') { - path = rb_file_expand_path(path, Qnil); - if (rb_safe_level() >= 1 && OBJ_TAINTED(path)) { - rb_raise(rb_eSecurityError, "loading from unsafe path %s", f); + tmp = rb_file_expand_path(path, Qnil); + if (safe_level >= 1 && OBJ_TAINTED(tmp)) { + rb_raise(rb_eSecurityError, "loading from unsafe file %s", f); } - OBJ_FREEZE(path); - f = StringValueCStr(path); + path = copy_path_class(tmp, path); + f = RSTRING_PTR(path); + expanded = 1; } - if (is_absolute_path(f) || is_explicit_relative(f)) { - if (rb_safe_level() >= 1 && !fpath_check(f)) { - rb_raise(rb_eSecurityError, "loading from unsafe file %s", f); + if (expanded || is_absolute_path(f) || is_explicit_relative(f)) { + if (safe_level >= 1 && !fpath_check(f)) { + rb_raise(rb_eSecurityError, "loading from unsafe path %s", f); } if (!file_load_ok(f)) return 0; - path = rb_file_expand_path(path, Qnil); + if (!expanded) + path = copy_path_class(rb_file_expand_path(path, Qnil), path); return path; } - if (rb_safe_level() >= 4) { + if (safe_level >= 4) { rb_raise(rb_eSecurityError, "loading from non-absolute path %s", f); } @@ -4706,19 +4740,17 @@ } } return 0; - found: - RBASIC(tmp)->klass = rb_obj_class(path); - OBJ_FREEZE(tmp); } else { return 0; /* no path, no load */ } - if (rb_safe_level() >= 1 && !fpath_check(f)) { + found: + if (safe_level >= 1 && !fpath_check(f)) { rb_raise(rb_eSecurityError, "loading from unsafe file %s", f); } - return tmp; + return copy_path_class(tmp, path); } static void -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/