[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]