なかだです。 Procは$SAFEを保存しますが、呼び出し側よりも低いレベルに戻すこと ができるのは危険ではないかといわれました。 説得力のある意見ではないかと思うのですが、どうでしょうか。
Index: eval.c =================================================================== RCS file: /pub/cvs/ruby/src/ruby/eval.c,v retrieving revision 1.673 diff -U2 -p -d -r1.673 eval.c --- eval.c 22 Jun 2004 14:59:25 -0000 1.673 +++ eval.c 25 Jun 2004 01:35:41 -0000 @@ -7900,10 +7900,15 @@ proc_get_safe_level(data) } -static void +static int proc_set_safe_level(data) VALUE data; { - if (!proc_safe_level_p(data)) return; - ruby_safe_level = proc_get_safe_level(data); + int old, safe; + + if (!proc_safe_level_p(data)) return -1; + old = ruby_safe_level; + safe = proc_get_safe_level(data); + if (safe > old) ruby_safe_level = safe; + return old; } @@ -8040,5 +8045,5 @@ proc_invoke(proc, args, self, klass) volatile VALUE result = Qundef; int state; - volatile int safe = ruby_safe_level; + volatile int safe; volatile VALUE old_wrapper = ruby_wrapper; struct RVarmap * volatile old_dvars = ruby_dyna_vars; @@ -8072,7 +8077,7 @@ proc_invoke(proc, args, self, klass) ruby_frame->iter = ITER_CUR; PUSH_TAG(pcall ? PROT_LAMBDA : PROT_NONE); + safe = proc_set_safe_level(proc); state = EXEC_TAG(); if (state == 0) { - proc_set_safe_level(proc); result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0, pcall | YIELD_PROC_CALL, avalue); @@ -8086,5 +8091,5 @@ proc_invoke(proc, args, self, klass) ruby_wrapper = old_wrapper; ruby_dyna_vars = old_dvars; - if (proc_safe_level_p(proc)) ruby_safe_level = safe; + if (safe >= 0) ruby_safe_level = safe; switch (state) { @@ -8370,5 +8375,6 @@ block_pass(self, node) int state; volatile int orphan; - volatile int safe = ruby_safe_level; + volatile int oldsafe; + int safe; if (NIL_P(proc)) { @@ -8414,8 +8420,9 @@ block_pass(self, node) PUSH_TAG(PROT_LOOP); + oldsafe = proc_set_safe_level(proc); + safe = ruby_safe_level; state = EXEC_TAG(); if (state == 0) { retry: - proc_set_safe_level(proc); if (safe > ruby_safe_level) ruby_safe_level = safe; @@ -8433,5 +8440,5 @@ block_pass(self, node) POP_ITER(); ruby_block = old_block; - if (proc_safe_level_p(proc)) ruby_safe_level = safe; + if (oldsafe >= 0) ruby_safe_level = safe; switch (state) {/* escape from orphan block */
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦