hash.c: add arity check for Hash#default_proc (and Hash.new); fix #6484

This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-03-08 16:14:26 +09:00
parent a7f3cfb711
commit 9a226c28bc
+20 -6
View File
@@ -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;
}