It’s possible for XS code to create hash entries with null values.
pp_helem and pp_slice were not taking that into account. In fact,
the core produces such hash entries, but they are rarely visible from
Perl. It’s good to check for them anyway.
'newHVhv on tied hash';
}
+# helem on entry with null value
+# This is actually a test for a Perl operator, not an XS API test. But it
+# requires a hash that can only be produced by XS (although recently it
+# could be encountered when tying hint hashes).
+{
+ my %h;
+ fill_hash_with_nulls(\%h);
+ eval{ $h{84} = 1 };
+ pass 'no crash when writing to hash elem with null value';
+ eval{ @h{85} = 1 };
+ pass 'no crash when writing to hash elem with null value via slice';
+}
+
done_testing;
exit;
svp = he ? &HeVAL(he) : NULL;
if (lval) {
- if (!svp || *svp == &PL_sv_undef) {
+ if (!svp || !*svp || *svp == &PL_sv_undef) {
DIE(aTHX_ PL_no_helem_sv, SVfARG(keysv));
}
if (localizing) {
SAVEHDELETE(hv, keysv);
}
}
- *MARK = svp ? *svp : &PL_sv_undef;
+ *MARK = svp && *svp ? *svp : &PL_sv_undef;
}
if (GIMME != G_ARRAY) {
MARK = ORIGMARK;
he = hv_fetch_ent(hv, keysv, lval && !defer, hash);
svp = he ? &HeVAL(he) : NULL;
if (lval) {
- if (!svp || *svp == &PL_sv_undef) {
+ if (!svp || !*svp || *svp == &PL_sv_undef) {
SV* lv;
SV* key2;
if (!defer) {
RETURN;
}
}
- sv = (svp ? *svp : &PL_sv_undef);
+ sv = (svp && *svp ? *svp : &PL_sv_undef);
/* Originally this did a conditional C<sv = sv_mortalcopy(sv)>; this
* was to make C<local $tied{foo} = $tied{foo}> possible.
* However, it seems no longer to be needed for that purpose, and