summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--eval.c21
-rw-r--r--test/ruby/test_refinement.rb21
3 files changed, 50 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index f61ea885e0..5a3ddc88aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Tue Nov 13 18:01:54 2012 Shugo Maeda <shugo@ruby-lang.org>
+
+ * eval.c (rb_mod_using): raise an ArgumentError if cyclic using is
+ detected. based on the patch by Charlie Somerville.
+ [ruby-core:49092] Bug #7308
+
+ * test/ruby/test_refinement.rb: related test.
+
Tue Nov 13 17:40:04 2012 NARUSE, Yui <naruse@ruby-lang.org>
* common.mk (vm_insnhelper.c): this target is useless and causes
diff --git a/eval.c b/eval.c
index 0f1d3d97d0..b90616d8e3 100644
--- a/eval.c
+++ b/eval.c
@@ -1135,6 +1135,26 @@ rb_using_module(NODE *cref, VALUE module)
rb_hash_foreach(refinements, using_refinement, (VALUE) cref);
}
+
+static int
+check_cyclic_using(VALUE mod, VALUE _, VALUE search)
+{
+ VALUE using_modules;
+ ID id_using_modules;
+ CONST_ID(id_using_modules, "__using_modules__");
+
+ if (mod == search) {
+ rb_raise(rb_eArgError, "cyclic using detected");
+ }
+
+ using_modules = rb_attr_get(mod, id_using_modules);
+ if (!NIL_P(using_modules)) {
+ rb_hash_foreach(using_modules, check_cyclic_using, search);
+ }
+
+ return ST_CONTINUE;
+}
+
/*
* call-seq:
* using(module) -> self
@@ -1150,6 +1170,7 @@ rb_mod_using(VALUE self, VALUE module)
VALUE using_modules;
Check_Type(module, T_MODULE);
+ check_cyclic_using(module, 0, self);
CONST_ID(id_using_modules, "__using_modules__");
using_modules = rb_attr_get(self, id_using_modules);
if (NIL_P(using_modules)) {
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index e367532ec5..3ca00ed912 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -801,4 +801,25 @@ class TestRefinement < Test::Unit::TestCase
p c.foo
INPUT
end
+
+ def test_circular_using_is_not_allowed
+ a = Module.new
+ b = Module.new
+
+ assert_raise ArgumentError do
+ a.module_eval do
+ using a
+ end
+ end
+
+ b.module_eval do
+ using a
+ end
+
+ assert_raise ArgumentError do
+ a.module_eval do
+ using b
+ end
+ end
+ end
end