From 8b7059b1a993d7ac934442e99623d9dbc5fe3ce8 Mon Sep 17 00:00:00 2001 From: Dave Mitchell Date: Fri, 2 Jul 2004 01:49:11 +0000 Subject: [perl #30258] utf8 POPSTACK crash on split execution split() does a SWITCHSTACK to directly split to an array, but if it subsequently dies (eg the regex triggers a 'use utf8' which is then denied by Safe), then the switch doesn't get undone. Add a new save type to allow for this. p4raw-id: //depot/perl@23023 --- pp.c | 10 ++++------ scope.c | 9 +++++++++ scope.h | 11 +++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/pp.c b/pp.c index 001b9be795..9425bca929 100644 --- a/pp.c +++ b/pp.c @@ -4439,7 +4439,6 @@ PP(pp_split) I32 origlimit = limit; I32 realarray = 0; I32 base; - AV *oldstack = PL_curstack; I32 gimme = GIMME_V; I32 oldsave = PL_savestack_ix; I32 make_mortal = 1; @@ -4488,8 +4487,7 @@ PP(pp_split) AvARRAY(ary)[i] = &PL_sv_undef; /* don't free mere refs */ } /* temporarily switch stacks */ - SWITCHSTACK(PL_curstack, ary); - PL_curstackinfo->si_stack = ary; + SAVESWITCHSTACK(PL_curstack, ary); make_mortal = 0; } } @@ -4658,7 +4656,6 @@ PP(pp_split) } } - LEAVE_SCOPE(oldsave); iters = (SP - PL_stack_base) - base; if (iters > maxiters) DIE(aTHX_ "Split loop"); @@ -4684,10 +4681,11 @@ PP(pp_split) } } + PUTBACK; + LEAVE_SCOPE(oldsave); /* may undo an earlier SWITCHSTACK */ + SPAGAIN; if (realarray) { if (!mg) { - SWITCHSTACK(ary, oldstack); - PL_curstackinfo->si_stack = oldstack; if (SvSMAGICAL(ary)) { PUTBACK; mg_set((SV*)ary); diff --git a/scope.c b/scope.c index 452ea774fe..54d4488344 100644 --- a/scope.c +++ b/scope.c @@ -1063,6 +1063,15 @@ Perl_leave_scope(pTHX_ I32 base) AvARRAY((PAD*)ptr)[off] = (SV*)SSPOPPTR; } break; + case SAVEt_SAVESWITCHSTACK: + { + dSP; + AV* t = (AV*)SSPOPPTR; + AV* f = (AV*)SSPOPPTR; + SWITCHSTACK(t,f); + PL_curstackinfo->si_stack = f; + } + break; case SAVEt_SET_SVFLAGS: { U32 val = (U32)SSPOPINT; diff --git a/scope.h b/scope.h index bbb55628fe..f86039dbd1 100644 --- a/scope.h +++ b/scope.h @@ -48,6 +48,7 @@ #define SAVEt_SHARED_PVREF 37 #define SAVEt_BOOL 38 #define SAVEt_SET_SVFLAGS 39 +#define SAVEt_SAVESWITCHSTACK 40 #ifndef SCOPE_SAVES_SIGNAL_MASK #define SCOPE_SAVES_SIGNAL_MASK 0 @@ -169,6 +170,16 @@ Closing bracket on a callback. See C and L. SSPUSHINT(SAVEt_COMPPAD); \ } STMT_END +#define SAVESWITCHSTACK(f,t) \ + STMT_START { \ + SSCHECK(3); \ + SSPUSHPTR((SV*)(f)); \ + SSPUSHPTR((SV*)(t)); \ + SSPUSHINT(SAVEt_SAVESWITCHSTACK); \ + SWITCHSTACK((f),(t)); \ + PL_curstackinfo->si_stack = (t); \ + } STMT_END + #ifdef USE_ITHREADS # define SAVECOPSTASH(c) SAVEPPTR(CopSTASHPV(c)) # define SAVECOPSTASH_FREE(c) SAVESHAREDPV(CopSTASHPV(c)) -- cgit v1.2.1