Skip to content

Commit

Permalink
Hash: check flags before accessing ifnone; ref #980
Browse files Browse the repository at this point in the history
  • Loading branch information
matz committed Feb 5, 2016
1 parent 25e4ec3 commit 3c73c31
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 13 deletions.
4 changes: 3 additions & 1 deletion include/mruby/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ KHASH_DECLARE(ht, mrb_value, mrb_hash_value, TRUE)
#define RHASH_PROCDEFAULT(h) RHASH_IFNONE(h)
MRB_API struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash);

#define MRB_HASH_PROC_DEFAULT 256
#define MRB_HASH_DEFAULT 1
#define MRB_HASH_PROC_DEFAULT 2
#define MRB_RHASH_DEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_DEFAULT)
#define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT)

/* GC functions */
Expand Down
45 changes: 33 additions & 12 deletions src/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,13 @@ mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
}

/* not found */
if (MRB_RHASH_PROCDEFAULT_P(hash)) {
return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
if (MRB_RHASH_DEFAULT_P(hash)) {
if (MRB_RHASH_PROCDEFAULT_P(hash)) {
return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
}
return RHASH_IFNONE(hash);
}
return RHASH_IFNONE(hash);
return mrb_nil_value();
}

MRB_API mrb_value
Expand Down Expand Up @@ -323,7 +326,10 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash)
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
ifnone = block;
}
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
if (!mrb_nil_p(ifnone)) {
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
}
return hash;
}

Expand Down Expand Up @@ -417,8 +423,13 @@ mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
mrb_get_args(mrb, "o", &ifnone);
mrb_hash_modify(mrb, hash);
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
RHASH(hash)->flags &= ~(MRB_HASH_PROC_DEFAULT);

RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
if (!mrb_nil_p(ifnone)) {
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
}
else {
RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
}
return ifnone;
}

Expand Down Expand Up @@ -468,7 +479,14 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
mrb_get_args(mrb, "o", &ifnone);
mrb_hash_modify(mrb, hash);
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
if (!mrb_nil_p(ifnone)) {
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
}
else {
RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
}

return ifnone;
}
Expand Down Expand Up @@ -561,12 +579,15 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
}
}

if (MRB_RHASH_PROCDEFAULT_P(hash)) {
return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value());
}
else {
return RHASH_IFNONE(hash);
if (MRB_RHASH_DEFAULT_P(hash)) {
if (MRB_RHASH_PROCDEFAULT_P(hash)) {
return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value());
}
else {
return RHASH_IFNONE(hash);
}
}
return mrb_nil_value();
}

/* 15.2.13.4.4 */
Expand Down

0 comments on commit 3c73c31

Please sign in to comment.