Since, for speed’s sake, pp_sort does not call PUSH/POPBLOCK for
every invocation of a sort subroutine, it fails to restore PL_curpm
after each call (POPBLOCK usually handles that). So the new values of
match vars like $1 when the sub returns are what it sees at the next
invocation.
This commit fixes this by resetting PL_curpm after each call to the
subroutine. There are actually three different functions for this
(S_sortcv*) so they all need modification.
const I32 oldsaveix = PL_savestack_ix;
const I32 oldscopeix = PL_scopestack_ix;
I32 result;
+ PMOP * const pm = PL_curpm;
PERL_ARGS_ASSERT_SORTCV;
LEAVE;
}
leave_scope(oldsaveix);
+ PL_curpm = pm;
return result;
}
const I32 oldscopeix = PL_scopestack_ix;
I32 result;
AV * const av = GvAV(PL_defgv);
+ PMOP * const pm = PL_curpm;
PERL_ARGS_ASSERT_SORTCV_STACKED;
LEAVE;
}
leave_scope(oldsaveix);
+ PL_curpm = pm;
return result;
}
const I32 oldscopeix = PL_scopestack_ix;
CV * const cv=MUTABLE_CV(PL_sortcop);
I32 result;
+ PMOP * const pm = PL_curpm;
PERL_ARGS_ASSERT_SORTCV_XSUB;
LEAVE;
}
leave_scope(oldsaveix);
+ PL_curpm = pm;
return result;
}
require 'test.pl';
}
use warnings;
-plan( tests => 160 );
+plan( tests => 162 );
# these shouldn't hang
{
{},
'[perl #77930] cx_stack reallocation during sort'
;
+
+# [perl #76026]
+# Match vars should not leak from one sort sub call to the next
+{
+ my $output = '';
+ sub soarter {
+ $output .= $1;
+ "Leakage" =~ /(.*)/;
+ 1
+ }
+ sub soarterdd($$) {
+ $output .= $1;
+ "Leakage" =~ /(.*)/;
+ 1
+ }
+
+ "Win" =~ /(.*)/;
+ my @b = sort soarter 0..2;
+
+ like $output, qr/^(?:Win)+\z/,
+ "Match vars do not leak from one plain sort sub to the next";
+
+ $output = '';
+
+ "Win" =~ /(.*)/;
+ @b = sort soarterdd 0..2;
+
+ like $output, qr/^(?:Win)+\z/,
+ 'Match vars do not leak from one $$ sort sub to the next';
+}