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