[#30408] Ruby 1.8.6 preview2 has been released — "Akinori MUSHA" <knu@...>

 Ruby 1.8.6 preview2 をリリースしました。

20 messages 2007/02/24
[#30414] fail to autoload at $SAFE==4 (Re: Ruby 1.8.6 preview2 has been released) — Hidetoshi NAGAI <nagai@...> 2007/02/25

永井@知能.九工大です.

[#30418] Re: fail to autoload at $SAFE==4 (Re: Ruby 1.8.6 preview2 has been released) — Nobuyoshi Nakada <nobu@...> 2007/02/25

なかだです。

[ruby-dev:30434] Re: fail to autoload at $SAFE==4

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-02-27 02:00:40 UTC
List: ruby-dev #30434
なかだです。

At Mon, 26 Feb 2007 00:50:48 +0900,
Hidetoshi NAGAI wrote in [ruby-dev:30419]:
> > > $SAFE==0 などで autoload が適切に設定されている場合,
> > > $SAFE の値に無関係にきちんと load されるべきと思いますし,
> > > 事実,これまではそのように働いていたのですが,
> > > 20070219 の commit の結果,うまく機能しないようになっています.
> > 
> > すいません。これでどうでしょう。
> 
> ありがとうございます.動くようになりました.
> ruby_1_8 および ruby_1_8_6 への commit をよろしくお願いいたします.

現在のコードがsearch_required()を呼ぶようになっている理由は、
requireは拡張子が指定されていなければ.rb, .soなどを探すという仕
様だからです。つまり、もしすでに拡張ライブラリがロードされてい
たとしても、$LOAD_PATH中におなじfeature名の.  rbファイルがあれ
ば、そちらが優先されるためにrb_provided()はfalseを返さなければ
なりませんが、前回のパッチでは拡張ライブラリとスクリプトライブ
ラリの両方がある場合には対応できません。

ということで考えたのが、以下の二つの案です。
(1) safe_levelを指定して探してくれるrb_provided()を追加する
(2) rb_provided()は拡張ライブラリについてはあきらめる

rb_provided()はautoload関連でしか使われていないので、とりあえず
は(2)でいいのではないかと思います。拡張ライブラリだけロードされ
た時点では未定義の定数がdefined?やautoload?で真を返すようになり
ますが、実際に参照されればconst_missingになるので、許容範囲では
なかろうかと。


Index: eval.c
===================================================================
--- eval.c	(revision 11898)
+++ eval.c	(working copy)
@@ -6938,4 +6938,7 @@ static const char *const loadable_ext[] 
 };
 
+static int rb_feature_p _((const char *, const char *, int));
+static int search_required _((VALUE, VALUE *, VALUE *));
+
 static int
 rb_feature_p(feature, ext, rb)
@@ -6974,5 +6977,5 @@ rb_feature_p(feature, ext, rb)
     if (loading_tbl) {
 	if (st_lookup(loading_tbl, (st_data_t)feature, 0)) {
-	    if (ext) return 'u';
+	    if (!ext) return 'u';
 	    return strcmp(ext, ".rb") ? 's' : 'r';
 	}
@@ -6994,19 +6997,22 @@ rb_feature_p(feature, ext, rb)
 }
 
-static int search_required(VALUE, VALUE *, VALUE *);
-
 int
 rb_provided(feature)
     const char *feature;
 {
-    VALUE fname, path;
+    const char *ext = strrchr(feature, '.');
 
-    if (rb_feature_p(feature, 0, Qfalse))
-	return Qtrue;
-    if (search_required(rb_str_new2(feature), &fname, &path) != 0) {
-	feature = RSTRING_PTR(fname);
-	if (rb_feature_p(feature, strrchr(feature, '.'), Qfalse))
-	    return Qtrue;
+    if (ext && !strchr(ext, '/')) {
+	if (strcmp(".rb", ext) == 0) {
+	    if (rb_feature_p(feature, ext, Qtrue)) return Qtrue;
+	    return Qfalse;
+	}
+	else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
+	    return Qfalse;	/* may be overriden by .rb file */
+	}
     }
+    if (rb_feature_p(feature, 0, Qfalse) == 'r')
+	return Qtrue;
+
     return Qfalse;
 }


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread