This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Stop local $_[0] from leaking
authorFather Chrysostomos <sprout@cpan.org>
Sun, 18 Nov 2012 06:49:57 +0000 (22:49 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 18 Nov 2012 22:02:35 +0000 (14:02 -0800)
commit1cdc9186cabf19ce52d3cfa09e46c4f4a28e59e1
treeab2b0aac7939b0a946cc519be5200726a3870195
parentc9ac52160c0ba46c0a6482d85efb06a330ad4541
Stop local $_[0] from leaking

local $_[0] puts the current $_[0] on to the savestack and gives the
array a brand new SV.  If the array is not marked REAL, it holds no
reference counts on its elements.  @_ is surreal by default.

The localisation code was making @_ hold a reference count on its new
element.  The restore code was assuming it had a reference count, so
everything worked out if $_[0] was not modified after localisation.

But if the array is surreal, then modifications to it will assume that
it does *not* hold a reference count on $_[0].  So doing shift, or
@_=undef would cause the new element to leak.

Also, taking a reference to the array (\@_) will trigger, making
the reference count of all elements increeas, likwies leaking the
new element.

Since there is only one REAL flag, which indicates that all elements
of the array are reference-counted, we cannot have some elements ref-
erence-counted and some not (which local $_[0] does), and have every-
thing behave correctly.

So the only solution is to reify arrays before localising
their elements.
scope.c
t/op/svleak.t