Subject: | Recursive MULTICALL prematurely freed CV |
Test script to make List::Util segfault:
use List::Util 'first';
sub foo {
if($comparison) {
return 1;
}
else {
local $comparison = 1;
first \&foo, 1,2,3;
}
}
for(1,2){
foo()
}
This is Perl Bug #78070, fixed in Perl 5.13.6:
•The XS multicall API no longer causes subroutines to lose reference
counts if called via the multicall interface from within those very
subroutines. This affects modules like List::Util. Calling one of its
functions with an active subroutine as the first argument could cause a
crash
So we can backport it here:
--- multicall.h~ 2012-11-05 10:41:35.487993000 -0800
+++ multicall.h 2012-11-05 10:41:58.861218000 -0800
@@ -154,8 +154,8 @@
#define POP_MULTICALL \
STMT_START {
\
- CvDEPTH(multicall_cv)--;
\
- LEAVESUB(multicall_cv);
\
+ if (! --CvDEPTH(multicall_cv))
\
+ LEAVESUB(multicall_cv);
\
POPBLOCK(cx,PL_curpm);
\
POPSTACK;
\
CATCH_SET(multicall_oldcatch);
\