mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
vm_method.c: fix infinite recursion
* vm_method.c (rb_method_entry_get_without_cache): get rid of infinite recursion at aliases in a subclass and a superclass. return actually defined class for other than singleton class. [ruby-core:60431] [Bug #9475] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45367 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
af723ec847
commit
3453070fbc
3 changed files with 63 additions and 2 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Thu Mar 20 12:31:26 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* vm_method.c (rb_method_entry_get_without_cache): get rid of
|
||||||
|
infinite recursion at aliases in a subclass and a superclass.
|
||||||
|
return actually defined class for other than singleton class.
|
||||||
|
[ruby-core:60431] [Bug #9475]
|
||||||
|
|
||||||
Wed Mar 19 17:13:06 2014 Eric Wong <e@80x24.org>
|
Wed Mar 19 17:13:06 2014 Eric Wong <e@80x24.org>
|
||||||
|
|
||||||
* time.c (time_mload): freeze and preserve marshal-loaded time zone
|
* time.c (time_mload): freeze and preserve marshal-loaded time zone
|
||||||
|
|
|
@ -132,4 +132,51 @@ class TestAlias < Test::Unit::TestCase
|
||||||
GC.verify_internal_consistency
|
GC.verify_internal_consistency
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_cyclic_zsuper
|
||||||
|
bug9475 = '[ruby-core:60431] [Bug #9475]'
|
||||||
|
|
||||||
|
a = Module.new do
|
||||||
|
def foo
|
||||||
|
"A"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
b = Class.new do
|
||||||
|
include a
|
||||||
|
attr_reader :b
|
||||||
|
|
||||||
|
def foo
|
||||||
|
@b ||= 0
|
||||||
|
raise SystemStackError if (@b += 1) > 1
|
||||||
|
# "foo from B"
|
||||||
|
super + "B"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
c = Class.new(b) do
|
||||||
|
alias orig_foo foo
|
||||||
|
|
||||||
|
def foo
|
||||||
|
# "foo from C"
|
||||||
|
orig_foo + "C"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
b.class_eval do
|
||||||
|
alias orig_foo foo
|
||||||
|
attr_reader :b2
|
||||||
|
|
||||||
|
def foo
|
||||||
|
@b2 ||= 0
|
||||||
|
raise SystemStackError if (@b2 += 1) > 1
|
||||||
|
# "foo from B (again)"
|
||||||
|
orig_foo + "B2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_nothing_raised(SystemStackError, bug9475) do
|
||||||
|
assert_equal("ABC", c.new.foo, bug9475)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
11
vm_method.c
11
vm_method.c
|
@ -578,8 +578,15 @@ rb_method_entry_get_without_cache(VALUE klass, ID id,
|
||||||
VALUE defined_class;
|
VALUE defined_class;
|
||||||
rb_method_entry_t *me = search_method(klass, id, &defined_class);
|
rb_method_entry_t *me = search_method(klass, id, &defined_class);
|
||||||
|
|
||||||
if (me && RB_TYPE_P(me->klass, T_ICLASS))
|
if (me) {
|
||||||
defined_class = me->klass;
|
switch (BUILTIN_TYPE(me->klass)) {
|
||||||
|
case T_CLASS:
|
||||||
|
if (RBASIC(klass)->flags & FL_SINGLETON) break;
|
||||||
|
/* fall through */
|
||||||
|
case T_ICLASS:
|
||||||
|
defined_class = me->klass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ruby_running) {
|
if (ruby_running) {
|
||||||
if (OPT_GLOBAL_METHOD_CACHE) {
|
if (OPT_GLOBAL_METHOD_CACHE) {
|
||||||
|
|
Loading…
Reference in a new issue