fix comppad handling for failures in eval 'qr/(?p{...})/'
Hugo van der Sanden [Wed, 17 Feb 1999 10:06:01 +0000 (10:06 +0000)]
Message-Id: <199902171006.KAA10204@crypt.compulink.co.uk>
Subject: Re: [5.005_53] panic: pad_free curpad

p4raw-id: //depot/perl@2963

regcomp.c
regexec.c
t/op/misc.t

index 5d4c0f0..5b4bdf3 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -1171,10 +1171,10 @@ reg(I32 paren, I32 *flagp)
 
                    rop = sv_compile_2op(sv, &sop, "re", &av);
 
-                   n = add_data(3, "nso");
+                   n = add_data(3, "nop");
                    PL_regcomp_rx->data->data[n] = (void*)rop;
-                   PL_regcomp_rx->data->data[n+1] = (void*)av;
-                   PL_regcomp_rx->data->data[n+2] = (void*)sop;
+                   PL_regcomp_rx->data->data[n+1] = (void*)sop;
+                   PL_regcomp_rx->data->data[n+2] = (void*)av;
                    SvREFCNT_dec(sv);
                }
                else {                                          /* First pass */
@@ -3123,13 +3123,30 @@ pregfree(struct regexp *r)
     }
     if (r->data) {
        int n = r->data->count;
+       AV* new_comppad = NULL;
+       AV* old_comppad;
+       SV** old_curpad;
+
        while (--n >= 0) {
            switch (r->data->what[n]) {
            case 's':
                SvREFCNT_dec((SV*)r->data->data[n]);
                break;
+           case 'p':
+               new_comppad = (AV*)r->data->data[n];
+               break;
            case 'o':
+               if (new_comppad == NULL)
+                   croak("panic: pregfree comppad");
+               old_comppad = PL_comppad;
+               old_curpad = PL_curpad;
+               PL_comppad = new_comppad;
+               PL_curpad = AvARRAY(new_comppad);
                op_free((OP_4tree*)r->data->data[n]);
+               PL_comppad = old_comppad;
+               PL_curpad = old_curpad;
+               SvREFCNT_dec((SV*)new_comppad);
+               new_comppad = NULL;
                break;
            case 'n':
                break;
index f53567e..6d0cf8d 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -1664,7 +1664,7 @@ regmatch(regnode *prog)
            n = ARG(scan);
            PL_op = (OP_4tree*)PL_regdata->data[n];
            DEBUG_r( PerlIO_printf(Perl_debug_log, "  re_eval 0x%x\n", PL_op) );
-           PL_curpad = AvARRAY((AV*)PL_regdata->data[n + 1]);
+           PL_curpad = AvARRAY((AV*)PL_regdata->data[n + 2]);
            PL_reg_magic->mg_len = locinput - PL_bostr;
            PL_regendp[0] = locinput;
 
index acef29d..2d19ee1 100755 (executable)
@@ -476,3 +476,10 @@ for (2..3) {
 print $x->foo;
 EXPECT
 new1new22DESTROY2new33DESTROY31DESTROY1
+########
+re();
+sub re {
+    my $re = join '', eval 'qr/(?p{ $obj->method })/';
+    $re;
+}
+EXPECT