diff --git a/ChangeLog b/ChangeLog index 7044869583..c2e7d640ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Tue Aug 6 16:14:32 2013 Shugo Maeda + + * vm_eval.c (eval_string_with_cref): copy cref to limit the scope of + refienements in the eval string. [ruby-core:56329] [Bug #8722] + + * test/ruby/test_refinement.rb: related test. + Tue Aug 6 12:23:12 2013 Tanaka Akira * bignum.c (rb_big_realloc): Use VALGRIND_MAKE_MEM_UNDEFINED to diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index f1f5e9d3e5..ffecebd5e8 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -929,6 +929,38 @@ class TestRefinement < Test::Unit::TestCase assert_equal("FooExt2#y Foo#y", FooFoo2ExtClient.invoke_y_on(foo)) end + def test_eval_scoping + assert_in_out_err([], <<-INPUT, ["HELLO WORLD", "dlrow olleh", "HELLO WORLD"], []) + module M + refine String do + def upcase + reverse + end + end + end + + puts "hello world".upcase + puts eval(%{using M; "hello world".upcase}) + puts "hello world".upcase + INPUT + end + + def test_eval_with_binding_scoping + assert_in_out_err([], <<-INPUT, ["HELLO WORLD", "dlrow olleh", "HELLO WORLD"], []) + module M + refine String do + def upcase + reverse + end + end + end + + puts "hello world".upcase + puts eval(%{using M; "hello world".upcase}, TOPLEVEL_BINDING) + puts eval(%{"hello world".upcase}, TOPLEVEL_BINDING) + INPUT + end + private def eval_using(mod, s) diff --git a/vm_eval.c b/vm_eval.c index ce61849f2c..4493c1c929 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -1186,6 +1186,8 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, volatile V rb_block_t block, *base_block; volatile int parse_in_eval; volatile int mild_compile_error; + NODE *orig_cref; + VALUE crefval; if (file == 0) { file = rb_sourcefilename(); @@ -1243,7 +1245,14 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, volatile V th->mild_compile_error--; th->parse_in_eval--; + if (!cref && base_block->iseq) { + orig_cref = rb_vm_get_cref(base_block->iseq, base_block->ep); + cref = NEW_CREF(Qnil); + crefval = (VALUE) cref; + COPY_CREF(cref, orig_cref); + } vm_set_eval_stack(th, iseqval, cref, base_block); + RB_GC_GUARD(crefval); if (0) { /* for debug */ VALUE disasm = rb_iseq_disasm(iseqval);