mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
hash.c: add arity check for Hash#default_proc (and Hash.new); fix #6484
This commit is contained in:
+20
-6
@@ -11,6 +11,7 @@
|
||||
#include <mruby/hash.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/internal.h>
|
||||
#include <mruby/presym.h>
|
||||
|
||||
@@ -1273,6 +1274,21 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
|
||||
mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), key);
|
||||
mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), val);
|
||||
}
|
||||
static void
|
||||
hash_set_default_proc(mrb_state *mrb, mrb_value hash, mrb_value proc)
|
||||
{
|
||||
struct RProc *p = mrb_proc_ptr(proc);
|
||||
if (MRB_PROC_STRICT_P(p)) {
|
||||
int n = mrb_proc_arity(p);
|
||||
if (n != 2 && (n >= 0 || n < -3)) {
|
||||
if (n < 0) n = -n-1;
|
||||
mrb_raisef(mrb, E_TYPE_ERROR, "default_proc takes two arguments (2 for %d)", n);
|
||||
}
|
||||
}
|
||||
mrb_iv_set(mrb, hash, MRB_SYM(ifnone), proc);
|
||||
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
|
||||
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
|
||||
}
|
||||
|
||||
/* 15.2.13.4.16 */
|
||||
/*
|
||||
@@ -1323,10 +1339,10 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash)
|
||||
if (ifnone_p) {
|
||||
mrb_argnum_error(mrb, 1, 0, 0);
|
||||
}
|
||||
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
|
||||
ifnone = block;
|
||||
hash_set_default_proc(mrb, hash, block);
|
||||
return hash;
|
||||
}
|
||||
if (!mrb_nil_p(ifnone)) {
|
||||
if (ifnone_p && !mrb_nil_p(ifnone)) {
|
||||
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
|
||||
mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
|
||||
}
|
||||
@@ -1482,14 +1498,12 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
|
||||
}
|
||||
mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
|
||||
if (!mrb_nil_p(ifnone)) {
|
||||
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
|
||||
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
|
||||
hash_set_default_proc(mrb, hash, ifnone);
|
||||
}
|
||||
else {
|
||||
RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
|
||||
RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
|
||||
}
|
||||
|
||||
return ifnone;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user