aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--test/ruby/test_refinement.rb32
-rw-r--r--vm_eval.c9
3 files changed, 48 insertions, 0 deletions
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 <shugo@ruby-lang.org>
+
+ * 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 <akr@fsij.org>
* 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);