1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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().


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23828 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2009-06-23 07:05:04 +00:00
parent 12811c5932
commit ff1b8b7593
4 changed files with 105 additions and 57 deletions

View file

@ -1,3 +1,16 @@
Tue Jun 23 16:04:59 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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@ruby-lang.org> Tue Jun 23 12:43:56 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* configure.in: remove PACKAGE_* macros generated by autotools. * configure.in: remove PACKAGE_* macros generated by autotools.

94
file.c
View file

@ -4590,6 +4590,12 @@ file_load_ok(const char *path)
return ret; return ret;
} }
int
rb_file_load_ok(const char *path)
{
return file_load_ok(path);
}
static int static int
is_explicit_relative(const char *path) is_explicit_relative(const char *path)
{ {
@ -4600,33 +4606,50 @@ is_explicit_relative(const char *path)
VALUE rb_get_load_path(void); 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 int
rb_find_file_ext(VALUE *filep, const char *const *ext) rb_find_file_ext(VALUE *filep, const char *const *ext)
{ {
const char *f = RSTRING_PTR(*filep); return rb_find_file_ext_safe(filep, ext, rb_safe_level());
VALUE fname, load_path, tmp; }
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; long i, j, fnlen;
int expanded = 0;
if (!ext[0]) return 0; if (!ext[0]) return 0;
if (f[0] == '~') { if (f[0] == '~') {
fname = rb_file_expand_path(*filep, Qnil); 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); rb_raise(rb_eSecurityError, "loading from unsafe file %s", f);
} }
OBJ_FREEZE(fname); f = RSTRING_PTR(fname);
f = StringValueCStr(fname);
*filep = fname; *filep = fname;
expanded = 1;
} }
if (is_absolute_path(f) || is_explicit_relative(f)) { if (expanded || is_absolute_path(f) || is_explicit_relative(f)) {
fname = rb_file_expand_path(*filep, Qnil); 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); fnlen = RSTRING_LEN(fname);
for (i=0; ext[i]; i++) { for (i=0; ext[i]; i++) {
rb_str_cat2(fname, ext[i]); rb_str_cat2(fname, ext[i]);
if (file_load_ok(StringValueCStr(fname))) { if (file_load_ok(RSTRING_PTR(fname))) {
OBJ_FREEZE(fname); *filep = copy_path_class(fname, *filep);
*filep = fname;
return (int)(i+1); return (int)(i+1);
} }
rb_str_set_len(fname, fnlen); rb_str_set_len(fname, fnlen);
@ -4634,7 +4657,11 @@ rb_find_file_ext(VALUE *filep, const char *const *ext)
return 0; 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; if (!load_path) return 0;
fname = rb_str_dup(*filep); fname = rb_str_dup(*filep);
@ -4650,9 +4677,7 @@ rb_find_file_ext(VALUE *filep, const char *const *ext)
if (RSTRING_LEN(str) == 0) continue; if (RSTRING_LEN(str) == 0) continue;
file_expand_path(fname, str, 0, tmp); file_expand_path(fname, str, 0, tmp);
if (file_load_ok(RSTRING_PTR(tmp))) { if (file_load_ok(RSTRING_PTR(tmp))) {
RBASIC(tmp)->klass = rb_obj_class(*filep); *filep = copy_path_class(tmp, *filep);
OBJ_FREEZE(tmp);
*filep = tmp;
return (int)(j+1); return (int)(j+1);
} }
FL_UNSET(tmp, FL_TAINT | FL_UNTRUSTED); FL_UNSET(tmp, FL_TAINT | FL_UNTRUSTED);
@ -4665,29 +4690,38 @@ rb_find_file_ext(VALUE *filep, const char *const *ext)
VALUE VALUE
rb_find_file(VALUE path) 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; VALUE tmp, load_path;
const char *f = StringValueCStr(path); const char *f = StringValueCStr(path);
int expanded = 0;
if (f[0] == '~') { if (f[0] == '~') {
path = rb_file_expand_path(path, Qnil); tmp = rb_file_expand_path(path, Qnil);
if (rb_safe_level() >= 1 && OBJ_TAINTED(path)) { if (safe_level >= 1 && OBJ_TAINTED(tmp)) {
rb_raise(rb_eSecurityError, "loading from unsafe path %s", f);
}
OBJ_FREEZE(path);
f = StringValueCStr(path);
}
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); rb_raise(rb_eSecurityError, "loading from unsafe file %s", f);
} }
path = copy_path_class(tmp, path);
f = RSTRING_PTR(path);
expanded = 1;
}
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; 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; return path;
} }
if (rb_safe_level() >= 4) { if (safe_level >= 4) {
rb_raise(rb_eSecurityError, "loading from non-absolute path %s", f); rb_raise(rb_eSecurityError, "loading from non-absolute path %s", f);
} }
@ -4706,19 +4740,17 @@ rb_find_file(VALUE path)
} }
} }
return 0; return 0;
found:
RBASIC(tmp)->klass = rb_obj_class(path);
OBJ_FREEZE(tmp);
} }
else { else {
return 0; /* no path, no load */ 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); rb_raise(rb_eSecurityError, "loading from unsafe file %s", f);
} }
return tmp; return copy_path_class(tmp, path);
} }
static void static void

View file

@ -345,6 +345,9 @@ VALUE rb_file_expand_path(VALUE, VALUE);
VALUE rb_file_s_absolute_path(int, VALUE *); VALUE rb_file_s_absolute_path(int, VALUE *);
VALUE rb_file_absolute_path(VALUE, VALUE); VALUE rb_file_absolute_path(VALUE, VALUE);
void rb_file_const(const char*, 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*); int rb_find_file_ext(VALUE*, const char* const*);
VALUE rb_find_file(VALUE); VALUE rb_find_file(VALUE);
char *rb_path_next(const char *); char *rb_path_next(const char *);

52
load.c
View file

@ -252,10 +252,9 @@ rb_provide(const char *feature)
NORETURN(static void load_failed(VALUE)); NORETURN(static void load_failed(VALUE));
void static void
rb_load(VALUE fname, int wrap) rb_load_internal(VALUE fname, int wrap)
{ {
VALUE tmp;
int state; int state;
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
volatile VALUE wrapper = th->top_wrapper; volatile VALUE wrapper = th->top_wrapper;
@ -266,14 +265,6 @@ rb_load(VALUE fname, int wrap)
rb_thread_t *volatile th0 = th; rb_thread_t *volatile th0 = th;
#endif #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 */ th->errinfo = Qnil; /* ensure */
if (!wrap) { if (!wrap) {
@ -324,6 +315,14 @@ rb_load(VALUE fname, int wrap)
} }
} }
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 void
rb_load_protect(VALUE fname, int wrap, int *state) rb_load_protect(VALUE fname, int wrap, int *state)
{ {
@ -355,10 +354,16 @@ rb_load_protect(VALUE fname, int wrap, int *state)
static VALUE static VALUE
rb_f_load(int argc, VALUE *argv) rb_f_load(int argc, VALUE *argv)
{ {
VALUE fname, wrap; VALUE fname, wrap, path;
rb_scan_args(argc, argv, "11", &fname, &wrap); 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; return Qtrue;
} }
@ -435,7 +440,7 @@ rb_f_require(VALUE obj, VALUE fname)
} }
static int static int
search_required(VALUE fname, volatile VALUE *path) search_required(VALUE fname, volatile VALUE *path, int safe_level)
{ {
VALUE tmp; VALUE tmp;
char *ext, *ftptr; char *ext, *ftptr;
@ -450,7 +455,7 @@ search_required(VALUE fname, volatile VALUE *path)
if (loading) *path = rb_str_new2(loading); if (loading) *path = rb_str_new2(loading);
return 'r'; 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), '.'); ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qtrue, Qtrue, &loading) || loading) if (!rb_feature_p(ftptr, ext, Qtrue, Qtrue, &loading) || loading)
*path = tmp; *path = tmp;
@ -466,7 +471,7 @@ search_required(VALUE fname, volatile VALUE *path)
tmp = rb_str_new(RSTRING_PTR(fname), ext - RSTRING_PTR(fname)); tmp = rb_str_new(RSTRING_PTR(fname), ext - RSTRING_PTR(fname));
#ifdef DLEXT2 #ifdef DLEXT2
OBJ_FREEZE(tmp); 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), '.'); ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading) if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading)
*path = tmp; *path = tmp;
@ -475,7 +480,7 @@ search_required(VALUE fname, volatile VALUE *path)
#else #else
rb_str_cat2(tmp, DLEXT); rb_str_cat2(tmp, DLEXT);
OBJ_FREEZE(tmp); 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), '.'); ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading) if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading)
*path = tmp; *path = tmp;
@ -488,7 +493,7 @@ search_required(VALUE fname, volatile VALUE *path)
if (loading) *path = rb_str_new2(loading); if (loading) *path = rb_str_new2(loading);
return 's'; 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), '.'); ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading) if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading)
*path = tmp; *path = tmp;
@ -501,8 +506,7 @@ search_required(VALUE fname, volatile VALUE *path)
return 'r'; return 'r';
} }
tmp = fname; tmp = fname;
type = rb_find_file_ext(&tmp, loadable_ext); type = rb_find_file_ext_safe(&tmp, loadable_ext, safe_level);
tmp = rb_file_expand_path(tmp, Qnil);
switch (type) { switch (type) {
case 0: case 0:
if (ft) if (ft)
@ -567,19 +571,15 @@ rb_require_safe(VALUE fname, int safe)
rb_set_safe_level_force(safe); rb_set_safe_level_force(safe);
FilePathValue(fname); FilePathValue(fname);
rb_set_safe_level_force(0); rb_set_safe_level_force(0);
found = search_required(fname, &path); found = search_required(fname, &path, safe);
if (found) { if (found) {
if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) { if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
result = Qfalse; result = Qfalse;
} }
else { else {
if (safe > 0 && OBJ_TAINTED(path)) {
rb_raise(rb_eSecurityError, "cannot load from insecure path - %s",
RSTRING_PTR(path));
}
switch (found) { switch (found) {
case 'r': case 'r':
rb_load(path, 0); rb_load_internal(path, 0);
break; break;
case 's': case 's':