develooper Front page | perl.perl5.porters | Postings from March 2003

Re: [perl #21411] [slippery] Postponed RE with split()

Thread Previous
From:
Enache Adrian
Date:
March 6, 2003 16:31
Subject:
Re: [perl #21411] [slippery] Postponed RE with split()
Message ID:
20030306221026.GA13330@ratsnest.hole
On Tue, Mar 04, 2003 at 02:20:15PM +0200, Enache Adrian wrote:
> On Sun, Mar 02, 2003 at 05:41:38PM +0000, hv@crypt.org wrote:
> > Enache Adrian <enache@rdslink.ro> wrote:
> > :Simpler example:
> > :$ perl -le 'print join "|", split /((??{$i++}))/,"-1-3-5-"'
> > :
> > :This should print '-|1|-|3|-|5|-' not '-|1|-|7|-|5|-'
> > :
> > :The expression inside (??{ ... }) corrupts the stack.
> > 
> > Thanks, patch applied as #18805.
> 
> $ perl -le 'split /(?{"FOO"})/,"abcde";print @_'
> SEGV

A patch which fixes the above if a more nice (IMHO) way
( without stack switching though ) follows. - The previous
patch left a chance for the stack to be reallocated during
the last, failed match.

It also fixes another little nasty bug:

$ perl -e 'split /(?{ split "" }/,"abc"'
SEGV

It has to do with regexp caching - that's only PL_regdata which
causes problems, but I think it's better to restore them all
(PL_regnpar, PL_regprecomp, etc).

Regards
Adi

------------------------------------------------------------------
--- /arc/perl-current/regexec.c	2003-03-02 18:34:00.000000000 +0200
+++ regexec.c	2003-03-06 17:34:07.000000000 +0200
@@ -2838,6 +2838,7 @@ S_regmatch(pTHX_ regnode *prog)
 	    COP *ocurcop = PL_curcop;
 	    PAD *old_comppad;
 	    SV *ret;
+	    struct regexp *oreg = PL_reg_re;
 	
 	    n = ARG(scan);
 	    PL_op = (OP_4tree*)PL_regdata->data[n];
@@ -2970,8 +2971,10 @@ S_regmatch(pTHX_ regnode *prog)
 		sw = SvTRUE(ret);
 		logical = 0;
 	    }
-	    else
+	    else {
 		sv_setsv(save_scalar(PL_replgv), ret);
+		cache_re(oreg);
+	    }
 	    break;
 	}
 	case OPEN:
--- /arc/perl-current/pp.c	2003-03-03 08:45:50.000000000 +0200
+++ pp.c	2003-03-06 18:53:05.000000000 +0200
@@ -4647,13 +4647,13 @@ PP(pp_split)
     }
     else {
 	maxiters += slen * rx->nparens;
-	while (s < strend && --limit
-/*	       && (!rx->check_substr
-		   || ((s = CALLREG_INTUIT_START(aTHX_ rx, sv, s, strend,
-						 0, NULL))))
-*/	       && CALLREGEXEC(aTHX_ rx, s, strend, orig,
-			      1 /* minend */, sv, NULL, 0))
+	while (s < strend && --limit)
 	{
+	    PUTBACK;
+	    i = CALLREGEXEC(aTHX_ rx, s, strend, orig, 1 , sv, NULL, 0);
+	    SPAGAIN;
+	    if (i == 0)
+		break;
 	    TAINT_IF(RX_MATCH_TAINTED(rx));
 	    if (RX_MATCH_COPIED(rx) && rx->subbeg != orig) {
 		m = s;
@@ -4692,7 +4692,6 @@ PP(pp_split)
 		}
 	    }
 	    s = rx->endp[0] + orig;
-	    PUTBACK;
 	}
     }
 
--- /arc/perl-current/t/op/pat.t	2003-03-02 19:39:51.000000000 +0200
+++ t/op/pat.t	2003-03-06 22:04:16.000000000 +0200
@@ -6,7 +6,7 @@
 
 $| = 1;
 
-print "1..994\n";
+print "1..996\n";
 
 BEGIN {
     chdir 't' if -d 't';
@@ -3142,8 +3142,16 @@ ok("bbbbac" =~ /$pattern/ && $1 eq 'a', 
 {
     my $i;
     ok('-1-3-5-' eq join('', split /((??{$i++}))/, '-1-3-5-'),
-	"[perl #21411] (??{ .. }) corrupts split's stack")
+	"[perl #21411] (??{ .. }) corrupts split's stack");
+    split /(?{'WOW'})/, 'abc';
+    ok('a|b|c' eq join ('|', @_),
+	"[perl #21411] (?{ .. }) version of the above");
 }
 
-# last test 994
+{
+    split /(?{ split "" })/, "abc";
+    ok(1,'cache_re & "(?{": it dumps core in 5.6.1 & 5.8.0');
+}
+
+# last test 996
 


Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About