make mg_clear() et al behave when RC==0
authorDavid Mitchell <davem@iabyn.com>
Wed, 6 Apr 2011 22:35:14 +0000 (23:35 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 6 Apr 2011 23:18:41 +0000 (00:18 +0100)
commit150b625d31233719d0d078c7d9ebe5ac46a6c4da
treeb33547b8ddc724e3df16471dc3054f2043cb810c
parent76422f81b675011beffbdb66c981a36b6fbf4a6b
make mg_clear() et al behave when RC==0

The functions S_save_magic() and S_restore_magic(), which are called by
mg_get(), mg_set(), mg_length(), mg_size() and mg_clear(),
are not robust when called with an SV whose reference count is zero.
Basically, one of the actions of S_save_magic() is to temporarily
increase the refcount of the SV, and then for S_restore_magic() to reduce
it again at the end, so that if any of the magic functions called
inbetween decrease the count, it won't be prematurely freed.
However, if the count starts at zero, then bumping it up and bringing it
back down to zero, triggers a spurious second freeing.

So, if its zero, just skip the whole bumping thing.

Now, we shouldn't really be calling these functions will a zero-refcount
SV, but these things happen, and its best to be robust.

In particular, this fixes RT #87860, which was ultimately triggered by a
bug in Set::Object 1.28 that managed to create an HV with null SvMAGIC
field, but with the RMG flag set.

When freeing that HV, sv_clear() skips doing mg_free() because SvMAGIC is
null, whereas later it calls Perl_hv_undef_flags, which calls mg_clear()
because it uses the test SvRMAGICAL(hv) (which is true).
mg.c