1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Prevent SystemStackError when calling super in module with activated refinement

Without this, if a refinement defines a method that calls super and
includes a module with a module that calls super and has a activated
refinement at the point super is called, the module method super call
will end up calling back into the refinement method, creating a loop.

Fixes [Bug #17007]
This commit is contained in:
Jeremy Evans 2020-07-10 14:38:00 -07:00
parent cb5127927a
commit eeef16e190
Notes: git 2020-07-28 00:18:55 +09:00
2 changed files with 34 additions and 0 deletions

View file

@ -484,6 +484,37 @@ class TestRefinement < Test::Unit::TestCase
assert_equal("M#baz C#baz", RefineModule.call_baz)
end
module RefineIncludeActivatedSuper
class C
def foo
["C"]
end
end
module M; end
refinement = Module.new do
R = refine C do
def foo
["R"] + super
end
include M
end
end
using refinement
M.define_method(:foo){["M"] + super()}
def self.foo
C.new.foo
end
end
def test_refine_include_activated_super
assert_equal(["R", "M", "C"], RefineIncludeActivatedSuper.foo)
end
def test_refine_neither_class_nor_module
assert_raise(TypeError) do
Module.new {

View file

@ -3034,6 +3034,9 @@ search_refined_method(rb_execution_context_t *ec, rb_control_frame_t *cfp, struc
if (ref_me) {
if (vm_cc_call(cc) == vm_call_super_method) {
const rb_control_frame_t *top_cfp = current_method_entry(ec, cfp);
if (refinement == find_refinement(CREF_REFINEMENTS(vm_get_cref(top_cfp->ep)), vm_cc_cme(cc)->owner)) {
continue;
}
const rb_callable_method_entry_t *top_me = rb_vm_frame_method_entry(top_cfp);
if (top_me && rb_method_definition_eq(ref_me->def, top_me->def)) {
continue;