[perl #37725] perl segfaults on reversed array reference
Dave Mitchell [Tue, 22 Nov 2005 16:32:42 +0000 (16:32 +0000)]
The 'for (reverse @a)' optimisation got its index wrong when
create LVALUE SVs for undef elements

p4raw-id: //depot/perl@26195

pp_ctl.c
pp_hot.c
t/op/loopctl.t

index a1f1117..45ca9ea 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1802,8 +1802,8 @@ PP(pp_enteriter)
            }
        }
        else if (PL_op->op_private & OPpITER_REVERSED) {
-           cx->blk_loop.itermax = -1;
-           cx->blk_loop.iterix = AvFILL(cx->blk_loop.iterary);
+           cx->blk_loop.itermax = 0;
+           cx->blk_loop.iterix = AvFILL(cx->blk_loop.iterary) + 1;
 
        }
     }
@@ -1811,8 +1811,8 @@ PP(pp_enteriter)
        cx->blk_loop.iterary = PL_curstack;
        AvFILLp(PL_curstack) = SP - PL_stack_base;
        if (PL_op->op_private & OPpITER_REVERSED) {
-           cx->blk_loop.itermax = MARK - PL_stack_base;
-           cx->blk_loop.iterix = cx->blk_oldsp;
+           cx->blk_loop.itermax = MARK - PL_stack_base + 1;
+           cx->blk_loop.iterix = cx->blk_oldsp + 1;
        }
        else {
            cx->blk_loop.iterix = MARK - PL_stack_base;
index 312eef7..173aca2 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1899,11 +1899,11 @@ PP(pp_iter)
            RETPUSHNO;
 
        if (SvMAGICAL(av) || AvREIFY(av)) {
-           SV ** const svp = av_fetch(av, cx->blk_loop.iterix--, FALSE);
+           SV ** const svp = av_fetch(av, --cx->blk_loop.iterix, FALSE);
            sv = svp ? *svp : Nullsv;
        }
        else {
-           sv = AvARRAY(av)[cx->blk_loop.iterix--];
+           sv = AvARRAY(av)[--cx->blk_loop.iterix];
        }
     }
     else {
index 11fb7c8..a8e2310 100644 (file)
@@ -31,7 +31,7 @@
 #
 #  -- .robin. <robin@kitsite.com>  2001-03-13
 
-print "1..46\n";
+print "1..47\n";
 
 my $ok;
 
@@ -992,3 +992,16 @@ print ($ok ? "ok 41\n" : "not ok 41\n");
     }
 
 }
+
+{
+    # [perl #37725]
+
+    $a37725[3] = 1; # use package var
+    $i = 2;
+    for my $x (reverse @a37725) {
+       $x = $i++;
+    }
+    print "@a37725" == "5 4 3 2" ? "" : "not ",
+       "ok 47 - reverse with empty slots (@a37725)\n";
+}
+