Skip to content

Commit

Permalink
[perl #121362] overload optimisation added a SEGV
Browse files Browse the repository at this point in the history
My recent commit 3d147ac to "speed up (non)overloaded derefs"
introduced a potential SEGV. In Perl_Gv_AMupdate(), the 'aux' variable is
set to HvAUX(hv). My patch used the value of the variable later on in the
function, but it turns out that by then, S_hsplit() may have been called,
and thus HvARRAY (and HvAUX()) may have been reallocated.

Issue first spotted by Andreas' awesome BBC service, and diagnosed by
Nicholas Clark.
  • Loading branch information
iabyn committed Mar 4, 2014
1 parent 04775fa commit 4547997
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
6 changes: 4 additions & 2 deletions gv.c
Expand Up @@ -2612,8 +2612,10 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
}
}
if (!deref_seen)
/* none of @{} etc overloaded; we can do $obj->[N] quicker */
aux->xhv_aux_flags |= HvAUXf_NO_DEREF;
/* none of @{} etc overloaded; we can do $obj->[N] quicker.
* NB - aux var invalid here, HvARRAY() could have been
* reallocated since it was assigned to */
HvAUX(stash)->xhv_aux_flags |= HvAUXf_NO_DEREF;

if (filled) {
AMT_AMAGIC_on(&amt);
Expand Down
31 changes: 30 additions & 1 deletion lib/overload.t
Expand Up @@ -48,7 +48,7 @@ package main;

$| = 1;
BEGIN { require './test.pl' }
plan tests => 5193;
plan tests => 5194;

use Scalar::Util qw(tainted);

Expand Down Expand Up @@ -2702,6 +2702,35 @@ EOF
);
}

{
# RT #121362
# splitting the stash HV while rebuilding the overload cache gave
# valgrind errors. This test code triggers such a split. It doesn't
# actually test anything; its just there for valgrind to spot
# problems.

package A_121362;

sub stringify { }
use overload '""' => 'stringify';

package B_121362;
our @ISA = qw(A_121362);

package main;

my $x = bless { }, 'B_121362';

for ('a'..'z') {
delete $B_121362::{stringify}; # delete cache entry
no strict 'refs';
*{"B_121362::$_"} = sub { }; # increase size of %B_121362
my $y = $x->{value}; # trigger cache add to %B_121362
}
pass("RT 121362");
}


{ # undefining the overload stash -- KEEP THIS TEST LAST
package ant;
use overload '+' => 'onion';
Expand Down

0 comments on commit 4547997

Please sign in to comment.