From: nobu.nakada@... Date: 2003-09-04T23:34:31+09:00 Subject: [ruby-dev:21346] Re: $SAFE=4 での autoload なかだです。 At Thu, 4 Sep 2003 17:23:32 +0900, Hidetoshi NAGAI wrote: > 登録済ということは,より低いセキュリティレベルで autoload メソッドの > 呼び出しが行われたはずですから,その呼び出し時点で問題がなかったのなら > ライブラリの require を行っても問題がなさそうに感じます. そうすると、requireはautoloadを呼び出したときの$SAFEで実行すべ きでしょうか。もしそうだとすれば、今はすでにautoloadされている 定数をさらにautoloadしようとしても何も変わりませんが、違う$SAFE で呼ばれたときにはどっちを優先すべきなんでしょう。 > ついでに,patch がなくて申し訳ないのですが, > $SAFE=4 で autoload に失敗したときの例外メッセージが > --------------------------------------------------- > Insecure operation `(null)' at level 4 (SecurityError) > --------------------------------------------------- > というようになってしまうのは修正すべきかと思います. そういえば、rb_provided()で一度ロードされるファイルを探しに行く ようになったのは、なんででしたっけ。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.530 diff -u -2 -p -r1.530 eval.c --- eval.c 2 Sep 2003 00:51:39 -0000 1.530 +++ eval.c 4 Sep 2003 11:45:45 -0000 @@ -5839,18 +5839,38 @@ rb_feature_p(feature, wait) { VALUE v; - char *f; + char *f, *ext = strrchr(feature, '.'); long i, len = strlen(feature); + int rb = 1, so = 1; + if (ext) { + if (strcmp(ext, ".rb") == 0) { + so = 0; + len = ext - feature; + } + else if (strcmp(ext, ".so") == 0 || strcmp(ext, ".o") == 0 || +#ifdef DLEXT2 + strcmp(ext, DLEXT2) == 0 || +#endif + strcmp(ext, DLEXT) == 0) { + rb = 0; + len = ext - feature; + } + } for (i = 0; i < RARRAY(rb_features)->len; ++i) { v = RARRAY(rb_features)->ptr[i]; f = StringValuePtr(v); - if (strcmp(f, feature) == 0) { - goto load_wait; - } - if (strncmp(f, feature, len) == 0) { - if (strcmp(f+len, ".so") == 0) { + if (strncmp(f, feature, len) != 0) continue; + ext = f + len; + if (so) { + if (strcmp(ext, ".so") == 0 || strcmp(ext, ".o") == 0 || +#ifdef DLEXT2 + strcmp(ext, DLEXT2) == 0 || +#endif + strcmp(ext, DLEXT) == 0) { return Qtrue; } - if (strcmp(f+len, ".rb") == 0) { + } + if (rb) { + if (strcmp(ext, ".rb") == 0) { if (wait) goto load_wait; return Qtrue; @@ -5890,12 +5910,5 @@ rb_provided(feature) const char *feature; { - VALUE f = rb_str_new2(feature); - - if (strrchr(feature, '.') == 0) { - if (rb_find_file_ext(&f, loadable_ext) == 0) { - return rb_feature_p(feature, Qfalse); - } - } - return rb_feature_p(RSTRING(f)->ptr, Qfalse); + return rb_feature_p(feature, Qfalse); } @@ -6068,4 +6081,16 @@ rb_require(fname) } +VALUE +rb_require_autoload(file, klass, id) + VALUE file, klass; + ID id; +{ + PUSH_FRAME(); + ruby_frame->last_class = klass; + ruby_frame->last_func = id; + rb_f_require(Qnil, file); + POP_FRAME(); +} + static void secure_visibility(self) Index: variable.c =================================================================== RCS file: /cvs/ruby/src/ruby/variable.c,v retrieving revision 1.102 diff -u -2 -p -r1.102 variable.c --- variable.c 30 Aug 2003 00:03:57 -0000 1.102 +++ variable.c 4 Sep 2003 09:08:13 -0000 @@ -1212,5 +1212,5 @@ rb_autoload_load(klass, id) } FL_UNSET(file, FL_TAINT); - rb_f_require(Qnil, file); + rb_require_autoload(file, klass, id); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦