Skip to content

Commit 9a226c2

Browse files
committed
hash.c: add arity check for Hash#default_proc (and Hash.new); fix mruby#6484
1 parent a7f3cfb commit 9a226c2

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

src/hash.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <mruby/hash.h>
1212
#include <mruby/string.h>
1313
#include <mruby/variable.h>
14+
#include <mruby/proc.h>
1415
#include <mruby/internal.h>
1516
#include <mruby/presym.h>
1617

@@ -1273,6 +1274,21 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
12731274
mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), key);
12741275
mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), val);
12751276
}
1277+
static void
1278+
hash_set_default_proc(mrb_state *mrb, mrb_value hash, mrb_value proc)
1279+
{
1280+
struct RProc *p = mrb_proc_ptr(proc);
1281+
if (MRB_PROC_STRICT_P(p)) {
1282+
int n = mrb_proc_arity(p);
1283+
if (n != 2 && (n >= 0 || n < -3)) {
1284+
if (n < 0) n = -n-1;
1285+
mrb_raisef(mrb, E_TYPE_ERROR, "default_proc takes two arguments (2 for %d)", n);
1286+
}
1287+
}
1288+
mrb_iv_set(mrb, hash, MRB_SYM(ifnone), proc);
1289+
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
1290+
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
1291+
}
12761292

12771293
/* 15.2.13.4.16 */
12781294
/*
@@ -1323,10 +1339,10 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash)
13231339
if (ifnone_p) {
13241340
mrb_argnum_error(mrb, 1, 0, 0);
13251341
}
1326-
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
1327-
ifnone = block;
1342+
hash_set_default_proc(mrb, hash, block);
1343+
return hash;
13281344
}
1329-
if (!mrb_nil_p(ifnone)) {
1345+
if (ifnone_p && !mrb_nil_p(ifnone)) {
13301346
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
13311347
mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
13321348
}
@@ -1482,14 +1498,12 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
14821498
}
14831499
mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone);
14841500
if (!mrb_nil_p(ifnone)) {
1485-
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
1486-
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
1501+
hash_set_default_proc(mrb, hash, ifnone);
14871502
}
14881503
else {
14891504
RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
14901505
RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
14911506
}
1492-
14931507
return ifnone;
14941508
}
14951509

0 commit comments

Comments
 (0)