From b245f7cd17b8e5e5a6f986fe1e7062b3696c6c83 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Thu, 21 Mar 2024 11:27:54 +1100 Subject: [PATCH] prepare_export_lexical: save PL_comppad safely When the pad being saved and the pad for PL_compcv is the same, in some cases the actual exports would result in reallocating the AvARRAY() for the saved PL_comppad. The LEAVE in finish_export_lexical() would restore the old PL_comppad (which is fine) and the pre-reallocation PL_curpad (which isn't fine). This would later panic. SAVECOMPPAD; restores PL_comppad on LEAVE and then restores PL_curpad from PL_comppad, preventing the desync between those values. It's unclear to me why only the save_BEGINs; causes this, but the fix does fix a real problem and prevents the panics that I'm aware of here. Fixes #21981 --- builtin.c | 5 +++-- lib/builtin.t | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/builtin.c b/builtin.c index eca9ca3c5edd..7ed8a61f217f 100644 --- a/builtin.c +++ b/builtin.c @@ -48,8 +48,9 @@ Perl_prepare_export_lexical(pTHX) /* We need to have PL_comppad / PL_curpad set correctly for lexical importing */ ENTER; SAVESPTR(PL_comppad_name); PL_comppad_name = PadlistNAMES(CvPADLIST(PL_compcv)); - SAVESPTR(PL_comppad); PL_comppad = PadlistARRAY(CvPADLIST(PL_compcv))[1]; - SAVESPTR(PL_curpad); PL_curpad = PadARRAY(PL_comppad); + SAVECOMPPAD(); + PL_comppad = PadlistARRAY(CvPADLIST(PL_compcv))[1]; + PL_curpad = PadARRAY(PL_comppad); } #define export_lexical(name, sv) S_export_lexical(aTHX_ name, sv) diff --git a/lib/builtin.t b/lib/builtin.t index a1fd4221ee3d..feaeb4c2c304 100644 --- a/lib/builtin.t +++ b/lib/builtin.t @@ -621,6 +621,15 @@ TODO: { } } +# github #21981 +{ + fresh_perl_is(<<'EOS', "", {}, "github 21981: panic in intro_my"); +use B; +BEGIN { B::save_BEGINs; } +use v5.39; +EOS +} + # vim: tabstop=4 shiftwidth=4 expandtab autoindent softtabstop=4 done_testing();