mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* eval.c (proc_set_safe_level, proc_invoke, rb_mod_define_method): not
set $SAFE for methods defined from Proc. [ruby-dev:23697] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
934064ba5a
commit
33b8591248
3 changed files with 42 additions and 3 deletions
|
@ -1,7 +1,10 @@
|
|||
Sat Jun 19 13:24:15 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
Sat Jun 19 13:27:01 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* eval.c (method_call): allow changing $SAFE. [ruby-dev:23713]
|
||||
|
||||
* eval.c (proc_set_safe_level, proc_invoke, rb_mod_define_method): not
|
||||
set $SAFE for methods defined from Proc. [ruby-dev:23697]
|
||||
|
||||
Sat Jun 19 01:10:12 2004 Kouhei Sutou <kou@cozmixng.org>
|
||||
|
||||
* sample/rss/tdiary_plugin/rss-recent.rb: added more information.
|
||||
|
|
9
eval.c
9
eval.c
|
@ -7877,9 +7877,12 @@ rb_f_binding(self)
|
|||
#define PROC_TSHIFT (FL_USHIFT+1)
|
||||
#define PROC_TMASK (FL_USER1|FL_USER2|FL_USER3)
|
||||
#define PROC_TMAX (PROC_TMASK >> PROC_TSHIFT)
|
||||
#define PROC_NOSAFE FL_USER4
|
||||
|
||||
#define SAFE_LEVEL_MAX PROC_TMASK
|
||||
|
||||
#define proc_safe_level_p(data) (!(RBASIC(data)->flags & PROC_NOSAFE))
|
||||
|
||||
static void
|
||||
proc_save_safe_level(data)
|
||||
VALUE data;
|
||||
|
@ -7900,6 +7903,7 @@ static void
|
|||
proc_set_safe_level(data)
|
||||
VALUE data;
|
||||
{
|
||||
if (!proc_safe_level_p(data)) return;
|
||||
ruby_safe_level = proc_get_safe_level(data);
|
||||
}
|
||||
|
||||
|
@ -8081,7 +8085,7 @@ proc_invoke(proc, args, self, klass)
|
|||
ruby_block = old_block;
|
||||
ruby_wrapper = old_wrapper;
|
||||
ruby_dyna_vars = old_dvars;
|
||||
ruby_safe_level = safe;
|
||||
if (proc_safe_level_p(proc)) ruby_safe_level = safe;
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
|
@ -8428,7 +8432,7 @@ block_pass(self, node)
|
|||
POP_TAG();
|
||||
POP_ITER();
|
||||
ruby_block = old_block;
|
||||
ruby_safe_level = safe;
|
||||
if (proc_safe_level_p(proc)) ruby_safe_level = safe;
|
||||
|
||||
switch (state) {/* escape from orphan block */
|
||||
case 0:
|
||||
|
@ -9147,6 +9151,7 @@ rb_mod_define_method(argc, argv, mod)
|
|||
struct BLOCK *block;
|
||||
|
||||
body = proc_clone(body);
|
||||
RBASIC(body)->flags |= PROC_NOSAFE;
|
||||
Data_Get_Struct(body, struct BLOCK, block);
|
||||
block->frame.last_func = id;
|
||||
block->frame.orig_func = id;
|
||||
|
|
|
@ -91,4 +91,35 @@ class TestProc < Test::Unit::TestCase
|
|||
assert_equal(10, Proc.new{|&b| b.call(10)}.call {|x| x})
|
||||
assert_equal(12, Proc.new{|a,&b| b.call(a)}.call(12) {|x| x})
|
||||
end
|
||||
|
||||
def test_safe
|
||||
safe = $SAFE
|
||||
c = Class.new
|
||||
x = c.new
|
||||
|
||||
p = proc {
|
||||
$SAFE += 1
|
||||
proc {$SAFE}
|
||||
}.call
|
||||
assert_equal(safe, $SAFE)
|
||||
assert_equal(safe + 1, p.call)
|
||||
assert_equal(safe, $SAFE)
|
||||
|
||||
c.class_eval {define_method(:safe, p)}
|
||||
assert_equal(safe, x.safe)
|
||||
assert_equal(safe, x.method(:safe).call)
|
||||
assert_equal(safe, x.method(:safe).to_proc.call)
|
||||
|
||||
p = proc {$SAFE += 1}
|
||||
assert_equal(safe + 1, p.call)
|
||||
assert_equal(safe, $SAFE)
|
||||
|
||||
c.class_eval {define_method(:inc, p)}
|
||||
assert_equal(safe + 1, proc {x.inc; $SAFE}.call)
|
||||
assert_equal(safe, $SAFE)
|
||||
assert_equal(safe + 1, proc {x.method(:inc).call; $SAFE}.call)
|
||||
assert_equal(safe, $SAFE)
|
||||
assert_equal(safe + 1, proc {x.method(:inc).to_proc.call; $SAFE}.call)
|
||||
assert_equal(safe, $SAFE)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue