This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
S_process_special_blocks() should use a new stack for BEGIN blocks.
authorNicholas Clark <nick@ccl4.org>
Fri, 4 Oct 2013 12:54:00 +0000 (14:54 +0200)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 23 Nov 2013 05:20:37 +0000 (21:20 -0800)
This avoids the stack moving underneath anything that directly or indirectly
calls Perl_load_module().

[Committer’s note:

 This fixes bug #119993.

 Furthermore, under STRESS_REALLOC, t/io/layers.t was crashing like this:

 $ ./perl -Ilib -e ' open(UTF, "<:raw:encoding(utf8)", 'tmp75851B') or die $!; ref #blahblahblahblahblahblahblahblahblah'
 Segmentation fault: 11

 (The comment seems to be necessary to make it crash.)

 It was happening because open() was causing a module to be loaded
 while the arguments to open() were still on the stack.
]

op.c

diff --git a/op.c b/op.c
index 030039d..8a60800 100644 (file)
--- a/op.c
+++ b/op.c
@@ -7957,8 +7957,10 @@ S_process_special_blocks(pTHX_ I32 floor, const char *const fullname,
     if (*name == 'B') {
        if (strEQ(name, "BEGIN")) {
            const I32 oldscope = PL_scopestack_ix;
+            dSP;
            if (floor) LEAVE_SCOPE(floor);
            ENTER;
+            PUSHSTACKi(PERLSI_REQUIRE);
            SAVECOPFILE(&PL_compiling);
            SAVECOPLINE(&PL_compiling);
            SAVEVPTR(PL_curcop);
@@ -7968,6 +7970,7 @@ S_process_special_blocks(pTHX_ I32 floor, const char *const fullname,
            GvCV_set(gv,0);             /* cv has been hijacked */
            call_list(oldscope, PL_beginav);
 
+            POPSTACK;
            LEAVE;
        }
        else