pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
pkg/59831: patch: fix perl 5.42.0 segfault compiling certain programs
>Number: 59831
>Category: pkg
>Synopsis: patch: fix perl 5.42.0 segfault compiling certain programs
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Dec 12 04:05:00 +0000 2025
>Originator: James Cook
>Release: pkgsrc trunk
>Organization:
>Environment:
NetBSD ucl.h.falsifian.org 10.1 NetBSD 10.1 (GENERIC) #0: Mon Dec 16 13:08:11 UTC 2024 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
perl 5.42.0 crashes compiling certain programs. I've included a patch, which is simply to apply upstream git commit 96673a4bb36.
See upstream bug report: https://github.com/perl/perl5/issues/23405
I also reported on the pkgsrc-users mailing list; start of thread: https://mail-index.netbsd.org/pkgsrc-users/2025/10/15/msg042082.html
>How-To-Repeat:
Run this command: perl -E 'for my($x,$y)($a->foo){}'
Result: Segmentation fault (core dumped)
After the patch, there is no segfault; instead perl (correctly) complains by outputting:
Can't call method "foo" on an undefined value at -e line 1.
>Fix:
This patch to pkgsrc fixes it for me. (Applied atop commit ac347f1c6531de16c74bc2743dcf25610cccd465 from the git mirror)
(Sorry, I didn't follow the documented convention of naming the patch after the modified file, because it made more sense to me to keep the patch as one file.)
diff /home/falsifian/co/pkgsrc
path + /home/falsifian/co/pkgsrc
commit - ac347f1c6531de16c74bc2743dcf25610cccd465
blob - d50ed876359c2873fda8cfbad50dd35b46aa6dbb
file + lang/perl5/distinfo
--- lang/perl5/distinfo
+++ lang/perl5/distinfo
@@ -8,6 +8,7 @@ SHA1 (patch-Makefile.SH) = 56203aea57c429a94760f039a97
SHA1 (patch-cpan_ExtUtils-MakeMaker_lib_ExtUtils_MM__BeOS.pm) = 79e5aeccfa272ca5ec08bffc616d8053ae90ac51
SHA1 (patch-cpan_ExtUtils-MakeMaker_lib_ExtUtils_MM__Unix.pm) = 996556f221eb0c75c316315462bf6cea6746e030
SHA1 (patch-cpan_ExtUtils-MakeMaker_t_MM__BeOS.t) = 9b0e7ab85fdab4887b1754599a8879bd7d9f36cc
+SHA1 (patch-fix_2-var_for_crash) = 77ae4219e11a484d78e4253785505a4b6450b287
SHA1 (patch-hints_cygwin.sh) = 5e2e7179336c9bc085bd2e83d22755a235ea1a4a
SHA1 (patch-hints_linux.sh) = 4baa8f80695687abb53d4f4e1830cf86db5b2bf7
SHA1 (patch-hints_netbsd.sh) = cb498170c18f1f429eed9be245cd1df24c7ad628
commit - ac347f1c6531de16c74bc2743dcf25610cccd465
blob - /dev/null
file + lang/perl5/patches/patch-fix_2-var_for_crash (mode 644)
--- /dev/null
+++ lang/perl5/patches/patch-fix_2-var_for_crash
@@ -0,0 +1,78 @@
+$NetBSD$
+
+Fix a segfault when compiling a 2-var for loop over builtin::indexed.
+
+This is upstream git commit 96673a4bb36, with the following commit
+message:
+
+ newFOROP: fix crash when optimizing 2-var for over builtin::indexed
+
+ OP_ENTERSUB isn't necessarily a LISTOP, apparently, so we can't just
+ grab its op_last. Instead, copy/paste logic from elsewhere in op.c to
+ find the cvop.
+
+ Also, avoid crashing on "fake" pad entries that represent lexical subs
+ from outer scopes by climbing up the scope chain until we reach a real
+ pad entry.
+
+ Fixes #23405.
+
+diff d83bd2549fce92d161cd621b02e1f3c83162a718 96673a4bb36a973a9a4c5cd0e5727a799789a32c
+commit - d83bd2549fce92d161cd621b02e1f3c83162a718
+commit + 96673a4bb36a973a9a4c5cd0e5727a799789a32c
+blob - d7aaca7fe73c0ae938178e0e2b4425d99a48d613
+blob + 6a5f236cdf86819af838c36eac8b262050aca834
+--- op.c
++++ op.c
+@@ -9671,7 +9671,7 @@ S_op_is_cv_xsub(pTHX_ OP *o, XSUBADDR_t xsub)
+ }
+
+ case OP_PADCV:
+- cv = (CV *)PAD_SVl(o->op_targ);
++ cv = find_lexical_cv(o->op_targ);
+ assert(cv && SvTYPE(cv) == SVt_PVCV);
+ break;
+
+@@ -9689,10 +9689,18 @@ S_op_is_cv_xsub(pTHX_ OP *o, XSUBADDR_t xsub)
+ static bool
+ S_op_is_call_to_cv_xsub(pTHX_ OP *o, XSUBADDR_t xsub)
+ {
+- if(o->op_type != OP_ENTERSUB)
++ if (o->op_type != OP_ENTERSUB)
+ return false;
+
+- OP *cvop = cLISTOPx(cUNOPo->op_first)->op_last;
++ /* entersub may be a UNOP, not a LISTOP, so we can't just use op_last */
++ OP *aop = cUNOPo->op_first;
++ if (!OpHAS_SIBLING(aop)) {
++ aop = cUNOPx(aop)->op_first;
++ }
++ aop = OpSIBLING(aop);
++ OP *cvop;
++ for (cvop = aop; OpHAS_SIBLING(cvop); cvop = OpSIBLING(cvop)) ;
++
+ return op_is_cv_xsub(cvop, xsub);
+ }
+
+blob - 2f6790aee7758e16c2c86374648e22a9304ca4fe
+blob + 035d1da07e9196a13b998ed41609d9a299aa9e20
+--- t/op/for-many.t
++++ t/op/for-many.t
+@@ -498,4 +498,17 @@ is($continue, 'xx', 'continue reached twice');
+ is("@have", "Pointy end Up Flamey end Down", 'for my ($one, $two)');
+ }
+
++# GH #23405 - segfaults when compiling 2-var for loops
++{
++ my $dummy = sub {};
++ for my ($x, $y) (main->$dummy) {}
++ pass '2-var for does not crash on method calls';
++
++ my sub dummy {}
++ sub {
++ for my ($x, $y) (dummy) {}
++ }->();
++ pass '2-var for does not crash on lexical sub calls';
++}
++
+ done_testing();
Home |
Main Index |
Thread Index |
Old Index