Front page | perl.perl5.porters |
Postings from July 2004
Re: [perl #30258] utf8 POPSTACK crash on split execution
Thread Previous
|
Thread Next
From:
Dave Mitchell
Date:
July 1, 2004 19:15
Subject:
Re: [perl #30258] utf8 POPSTACK crash on split execution
Message ID:
20040702022315.GD1941@iabyn.com
On Sun, Jun 13, 2004 at 10:27:07PM -0000, Rusty Conover wrote:
> While attempting to do a split call in a Safe compartment
> which normally handles utf8 data fine, a "panic: POPSTACK"
> occurs.
>
> Code to reproduce crash:
>
> use Safe;
> use Encode qw(decode);
> my $c = new Safe("Bla");
> # Put the data in the safe package
> $Bla::foo = decode("latin1", "x , yzäöü");
> # Convert the variable to be marked as utf8
> $Bla::foo =~ /\s/;
>
> $c->reval(q(split /[\s,\0]+/, $foo;
> 1)) || die $@;
Thanks for the report. What's happening is as follows:
Because the string being split is UTF8 encoded, exceuting the regex
causes a 'use utf8' to be executed behind the scenes. Since this involves
doing stuff not aloowed by Safe, it dies, and is caught by the eval.
However, when split() splits to an array, as an ompimisation it switches
thethe array and the current stack, so the split happens directly on the
array rather than copying stuff back off the stack. When the program dies,
the stack isn't switched back.
The patch below fixes it - it's been applied to the current development
version of Perl.
Nick - I'm not sure this should be integrated into 5.8.x - all this
stack switching is hair-raising stuff, and I'm not yet convinced that this
is the best fix for it.
Dave.
--
Never do today what you can put off till tomorrow.
Change 23023 by davem@davem-percy on 2004/07/02 01:49:11
[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.
Affected files ...
... //depot/perl/pp.c#420 edit
... //depot/perl/scope.c#123 edit
... //depot/perl/scope.h#66 edit
Differences ...
==== //depot/perl/pp.c#420 (text) ====
@@ -4439,7 +4439,6 @@
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 @@
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 @@
}
}
- LEAVE_SCOPE(oldsave);
iters = (SP - PL_stack_base) - base;
if (iters > maxiters)
DIE(aTHX_ "Split loop");
@@ -4684,10 +4681,11 @@
}
}
+ 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);
==== //depot/perl/scope.c#123 (text) ====
@@ -1063,6 +1063,15 @@
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;
==== //depot/perl/scope.h#66 (text) ====
@@ -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 @@
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))
Thread Previous
|
Thread Next