From: James Cook Subject: [patch] Re: OpenBSD perl 5.42.0 - Call for Testing To: Andrew Hewus Fresh Cc: tech@openbsd.org Date: Sat, 03 Jan 2026 17:29:03 +0000 Andrew Hewus Fresh wrote: > Yet another perl update, this time to 5.42.0. There is talk about a .1 > release, but it didn't sound like anything that should block this update. There is a regression in 5.42.0: a segfault which is fairly easy to encounter. Here is a simple way to trigger it: perl -c -wE 'for my ($x, $y) (Bar->foo) {}' This causes perl 5.42.0 to segfault. Perl 5.40.0 says "-e syntax OK". I've included the upstream fix as a patch. I would be grateful if it could be included in the next OpenBSD release. The problem is documented here: https://github.com/perl/perl5/issues/23405 The below patch is upstream commit 96673a4b, which (when I asked in October) people on #perl in libera.chat thought was a reasonable thing to apply to 5.40.0. It is perhaps worth noting that the October perl5-porters mailing list post about a 5.42.1 maintenance release suggested it would be worth it even if it only included that commit. Although I have only minimally tested this on OpenBSD, I can say that on NetBSD, the full perl test suite passed when I applied that same change to the 5.40.0 source (and it's the patch is in pkgsrc). (BTW, is there a reliable way to build/test only gnu/usr.bin/perl in OpenBSD's source tree? In order to test this patch, I just followed the release(8) instructions excluding xenocara, which feels like overkill, but I didn't want to make assumptions (e.g: I can just follow perl's build instructions) or spend too much time digging into the build system internals.) -- James diff /usr/src path + /usr/src commit - 287000ffa12fe34ef71791da513207ea48a4b740 blob - f616532c491cebc2d5dc89f124135ff4a9841281 file + gnu/usr.bin/perl/op.c --- gnu/usr.bin/perl/op.c +++ gnu/usr.bin/perl/op.c @@ -9665,7 +9665,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; @@ -9683,10 +9683,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); } commit - 287000ffa12fe34ef71791da513207ea48a4b740 blob - 2f6790aee7758e16c2c86374648e22a9304ca4fe file + gnu/usr.bin/perl/t/op/for-many.t --- gnu/usr.bin/perl/t/op/for-many.t +++ gnu/usr.bin/perl/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();