summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFrancois Chagnon <[email protected]>2016-11-14 16:49:45 -0500
committerBouke van der Bijl <[email protected]>2016-11-24 10:23:31 -0500
commit1ec5994377b45b0299a9c4e6e7ab275792d81bc9 (patch)
tree855977357c0ac152e2246b94ff27c31fbafe1df1
parenta630c4f413f6af764e68210430e8b61a435d38d7 (diff)
downloadmruby-1ec5994377b45b0299a9c4e6e7ab275792d81bc9.tar.gz
mruby-1ec5994377b45b0299a9c4e6e7ab275792d81bc9.zip
Fix calling .arity on Proc with undefined `initialize`
Reported by @bouk
-rw-r--r--mrbgems/mruby-proc-ext/src/proc.c3
-rw-r--r--mrbgems/mruby-proc-ext/test/proc.rb11
-rw-r--r--src/proc.c15
-rw-r--r--test/t/proc.rb11
4 files changed, 33 insertions, 7 deletions
diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c
index c8c8f1aa1..34f6230dc 100644
--- a/mrbgems/mruby-proc-ext/src/proc.c
+++ b/mrbgems/mruby-proc-ext/src/proc.c
@@ -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);
}
diff --git a/mrbgems/mruby-proc-ext/test/proc.rb b/mrbgems/mruby-proc-ext/test/proc.rb
index 75e11dd93..7a078aabf 100644
--- a/mrbgems/mruby-proc-ext/test/proc.rb
+++ b/mrbgems/mruby-proc-ext/test/proc.rb
@@ -58,6 +58,17 @@ assert('Proc#parameters') do
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
diff --git a/src/proc.c b/src/proc.c
index 1620bddf8..4f770932b 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -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;
@@ -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);
diff --git a/test/t/proc.rb b/test/t/proc.rb
index 888b7d56a..bc9821f7c 100644
--- a/test/t/proc.rb
+++ b/test/t/proc.rb
@@ -46,6 +46,17 @@ assert('Proc#arity', '15.2.17.4.2') do
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 }