From 509590c18df04900490e73a0d2cf25035c978f6c Mon Sep 17 00:00:00 2001 From: Pete Kinnecom Date: Fri, 19 Jul 2024 20:36:46 +0000 Subject: [PATCH 1/2] Method missing kwargs test failure: Fail: Method#call with undefined method -- only kwargs (mrbgems: mruby-method) - Assertion[6] NoMethodError exception expected, not Class: Message: - Assertion[9] Expected: {:kwarg1=>:val1, :kwarg2=>:val2} Actual: [:foo] --- mrbgems/mruby-method/test/method.rb | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/mrbgems/mruby-method/test/method.rb b/mrbgems/mruby-method/test/method.rb index 8966ee085..005403bc5 100644 --- a/mrbgems/mruby-method/test/method.rb +++ b/mrbgems/mruby-method/test/method.rb @@ -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? From 890dda79d08ffbbb1d3774816be95133855e37f1 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 20 Jul 2024 16:25:11 +0900 Subject: [PATCH 2/2] Protect keyword arguments in `prepare_missing()` Previously, keyword arguments were lost if no positional arguments were passed. Fixed #6304 --- src/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm.c b/src/vm.c index d9416d41b..8830ca332 100644 --- a/src/vm.c +++ b/src/vm.c @@ -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));