* 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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37646 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shugo 2012-11-13 09:05:18 +00:00
Родитель e7659bd2fd
Коммит 684aa1f985
3 изменённых файлов: 50 добавлений и 0 удалений

Просмотреть файл

@ -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

21
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)) {

Просмотреть файл

@ -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