diff --git a/perl-5.27.5-perl-132442-Fix-stack-with-do-my-sub-l-1.patch b/perl-5.27.5-perl-132442-Fix-stack-with-do-my-sub-l-1.patch new file mode 100644 index 0000000..9d33d9c --- /dev/null +++ b/perl-5.27.5-perl-132442-Fix-stack-with-do-my-sub-l-1.patch @@ -0,0 +1,105 @@ +From 695d6585affc8f13711f013329fb4810ab89d833 Mon Sep 17 00:00:00 2001 +From: Father Chrysostomos +Date: Tue, 14 Nov 2017 18:55:55 -0800 +Subject: [PATCH] [perl #132442] Fix stack with do {my sub l; 1} +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A block in perl usually compiles to a leave op with an enter inside +it, followed by the statements: + + leave + enter + nextstate + ... expr ... + nextstate + ... expr ... + +If a block contains only one statement, and that statement is suffic- +iently innocuous, then the enter/leave pair to create the scope at run +time get skipped, and instead we have a simple scope op which is not +even executed: + + scope + ex-nextstate + ... expr ... + +The nextstate in this case also gets nulled. + +In the case of do { my sub l; 1 } we were getting a variation of the +latter, that looked like this: + + scope + introcv + clonecv + nextstate + ... expr ... + +The problem here is that nextstate resets the stack, even though a new +scope has not been pushed, so we end up with all existing stack items +from the *outer* scope getting clobbered. + +One can have fun with this and erase everything pushed on to the stack +so far in a given statement: + +$ ./perl -le 'print join "-", 1..10, do {my sub l; ","}, 11..20' +11,12,13,14,15,16,17,18,19,20 + +Here I replaced the first argument to join() from within the do{} +block, after having cleared the stack. + +Why was the op tree was getting muddled up like this? The ‘my sub’ +declaration does not immediately add any ops to the op tree; those ops +get added when the current scope finishing compiling, since those ops +must be inserted at the beginning of the block. + +I have not fully looked into the order that things happen, and why the +nextstate op does not get nulled; but it did not matter, because of +the simple fix: Treat lexical sub declarations as ‘not innocuous’ by +setting the HINT_BLOCK_SCOPE flag when a lexical sub is declared. +Thus, we end up with an enter/leave pair, which creates a +proper scope. + +Signed-off-by: Petr Písař +--- + op.c | 2 ++ + t/op/lexsub.t | 5 ++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/op.c b/op.c +index 8fa5aad876..c617ad2a00 100644 +--- a/op.c ++++ b/op.c +@@ -9243,6 +9243,8 @@ Perl_newMYSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) + + PERL_ARGS_ASSERT_NEWMYSUB; + ++ PL_hints |= HINT_BLOCK_SCOPE; ++ + /* Find the pad slot for storing the new sub. + We cannot use PL_comppad, as it is the pad owned by the new sub. We + need to look in CvOUTSIDE and find the pad belonging to the enclos- +diff --git a/t/op/lexsub.t b/t/op/lexsub.t +index 3fa17acdda..f085cd97e8 100644 +--- a/t/op/lexsub.t ++++ b/t/op/lexsub.t +@@ -7,7 +7,7 @@ BEGIN { + *bar::is = *is; + *bar::like = *like; + } +-plan 149; ++plan 150; + + # -------------------- our -------------------- # + +@@ -957,3 +957,6 @@ like runperl( + { + my sub h; sub{my $x; sub{h}} + } ++ ++is join("-", qw(aa bb), do { my sub lleexx; 123 }, qw(cc dd)), ++ "aa-bb-123-cc-dd", 'do { my sub...} in a list [perl #132442]'; +-- +2.13.6 + diff --git a/perl.spec b/perl.spec index 367794c..710a7ad 100644 --- a/perl.spec +++ b/perl.spec @@ -233,6 +233,10 @@ Patch68: perl-5.26.1-Fix-deparsing-of-transliterations-with-unprintable-c # in upstream after 5.27.5 Patch69: perl-5.26.1-fix-do-dir-returning-no.patch +# Fix stack manipulation when a lexical subroutine is defined in a do block in +# a member of an iteration list, RT#132442, in upstream after 5.27.5 +Patch70: perl-5.27.5-perl-132442-Fix-stack-with-do-my-sub-l-1.patch + # Link XS modules to libperl.so with EU::CBuilder on Linux, bug #960048 Patch200: perl-5.16.3-Link-XS-modules-to-libperl.so-with-EU-CBuilder-on-Li.patch @@ -2817,6 +2821,7 @@ Perl extension for Version Objects %patch67 -p1 %patch68 -p1 %patch69 -p1 +%patch70 -p1 %patch200 -p1 %patch201 -p1 @@ -2860,6 +2865,7 @@ perl -x patchlevel.h \ 'Fedora Patch67: Fix a crash when untying an object witout a stash' \ 'Fedora Patch68: Fix deparsing of transliterations with unprintable characters (RT#132405)' \ 'Fedora Patch69: Fix error reporting on do() on a directory (RT#125774)' \ + 'Fedora Patch70: Fix stack manipulation when a lexical subroutine is defined in a do block in a member of an iteration list (RT#132442)' \ 'Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux' \ 'Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux' \ %{nil} @@ -5156,6 +5162,8 @@ popd - Fix a crash when untying an object witout a stash - Fix deparsing of transliterations with unprintable characters (RT#132405) - Fix error reporting on do() on a directory (RT#125774) +- Fix stack manipulation when a lexical subroutine is defined in a do block in + a member of an iteration list (RT#132442) * Mon Sep 25 2017 Jitka Plesnikova - 4:5.26.1-401 - Update perl(:MODULE_COMPAT)