Skip to content

Commit

Permalink
Fix calling .arity on Proc with undefined initialize
Browse files Browse the repository at this point in the history
Reported by @bouk
  • Loading branch information
Francois Chagnon authored and bouk committed Nov 24, 2016
1 parent a630c4f commit 1ec5994
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 7 deletions.
3 changes: 3 additions & 0 deletions mrbgems/mruby-proc-ext/src/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ mrb_proc_parameters(mrb_state *mrb, mrb_value self)
// TODO cfunc aspec is not implemented yet
return mrb_ary_new(mrb);
}
if (!irep) {
return mrb_ary_new(mrb);
}
if (!irep->lv) {
return mrb_ary_new(mrb);
}
Expand Down
11 changes: 11 additions & 0 deletions mrbgems/mruby-proc-ext/test/proc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@
assert_equal([[:req, :a], [:req, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:req, :f], [:req, :g], [:block, :h]], lambda {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters)
end

assert('Proc#parameters with uninitialized Proc') do
begin
Proc.alias_method(:original_initialize, :initialize)
Proc.remove_method(:initialize)
assert_equal [], Proc.new{|a, b, c| 1}.parameters
ensure
Proc.alias_method(:initialize, :original_initialize)
Proc.remove_method(:original_initialize)
end
end

assert('Proc#to_proc') do
proc = Proc.new {}
assert_equal proc, proc.to_proc
Expand Down
15 changes: 8 additions & 7 deletions src/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,13 @@ mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self)
return (p->body.func)(mrb, self);
}

mrb_code*
mrb_proc_iseq(mrb_state *mrb, struct RProc *p)
{
return p->body.irep->iseq;
}

/* 15.2.17.4.2 */
static mrb_value
mrb_proc_arity(mrb_state *mrb, mrb_value self)
{
struct RProc *p = mrb_proc_ptr(self);
mrb_code *iseq = mrb_proc_iseq(mrb, p);
struct mrb_irep *irep;
mrb_code *iseq;
mrb_aspec aspec;
int ma, op, ra, pa, arity;

Expand All @@ -208,6 +203,12 @@ mrb_proc_arity(mrb_state *mrb, mrb_value self)
return mrb_fixnum_value(-1);
}

irep = p->body.irep;
if (!irep) {
return mrb_fixnum_value(0);
}

iseq = irep->iseq;
/* arity is depend on OP_ENTER */
if (GET_OPCODE(*iseq) != OP_ENTER) {
return mrb_fixnum_value(0);
Expand Down
11 changes: 11 additions & 0 deletions test/t/proc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@
assert_equal(-1, g)
end

assert('Proc#arity with unitialized Proc') do
begin
Proc.alias_method(:original_initialize, :initialize)
Proc.remove_method(:initialize)
assert_equal 0, Proc.new{|a, b, c| 1}.arity
ensure
Proc.alias_method(:initialize, :original_initialize)
Proc.remove_method(:original_initialize)
end
end

assert('Proc#call', '15.2.17.4.3') do
a = 0
b = Proc.new { a += 1 }
Expand Down

0 comments on commit 1ec5994

Please sign in to comment.