mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge pull request #6305 from dearblue/method_missing
Protect keyword arguments in `prepare_missing()`
This commit is contained in:
@@ -138,6 +138,36 @@ assert 'Method#call with undefined method' do
|
||||
assert_raise(NoMethodError) { m.call(:arg1, :arg2) }
|
||||
end
|
||||
|
||||
assert 'Method#call with undefined method -- only kwargs' do
|
||||
c = Class.new {
|
||||
attr_accessor :m, :argv, :kwargs
|
||||
def respond_to_missing?(m, b)
|
||||
m == :foo
|
||||
end
|
||||
|
||||
def method_missing(m, *argv, **kwargs)
|
||||
@m = m
|
||||
@argv = argv
|
||||
@kwargs = kwargs
|
||||
super
|
||||
end
|
||||
}
|
||||
cc = c.new
|
||||
assert_kind_of Method, cc.method(:foo)
|
||||
|
||||
# Calling cc.method(:foo) works
|
||||
assert_raise(NoMethodError) { cc.method(:foo).call(kwarg1: :val1, kwarg2: :val2) }
|
||||
assert_equal :foo, cc.m
|
||||
assert_equal [], cc.argv
|
||||
assert_equal({ kwarg1: :val1, kwarg2: :val2 }, cc.kwargs)
|
||||
|
||||
# calling cc.foo fails
|
||||
assert_raise(NoMethodError) { cc.foo(kwarg1: :val1, kwarg2: :val2) }
|
||||
assert_equal :foo, cc.m
|
||||
assert_equal [], cc.argv
|
||||
assert_equal({ kwarg1: :val1, kwarg2: :val2 }, cc.kwargs)
|
||||
end
|
||||
|
||||
assert 'Method#source_location' do
|
||||
skip if proc{}.source_location.nil?
|
||||
|
||||
|
||||
@@ -629,7 +629,6 @@ prepare_missing(mrb_state *mrb, mrb_callinfo *ci, mrb_value recv, mrb_sym mid, m
|
||||
stack_extend(mrb, 4);
|
||||
|
||||
argv = &ci->stack[1]; /* maybe reallocated */
|
||||
argv[0] = args;
|
||||
if (ci->nk == 0) {
|
||||
argv[1] = blk;
|
||||
}
|
||||
@@ -638,6 +637,7 @@ prepare_missing(mrb_state *mrb, mrb_callinfo *ci, mrb_value recv, mrb_sym mid, m
|
||||
argv[1] = argv[ci->n];
|
||||
argv[2] = blk;
|
||||
}
|
||||
argv[0] = args; /* must be replaced after saving argv[0] as it may be a keyword argument */
|
||||
ci->n = CALL_MAXARGS;
|
||||
/* ci->nk is already set to zero or CALL_MAXARGS */
|
||||
mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
|
||||
|
||||
Reference in New Issue
Block a user