RT #63790: &{PL_sv_yes} corrupted mark stack
authorDavid Mitchell <davem@iabyn.com>
Sat, 30 Oct 2010 19:15:18 +0000 (20:15 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sat, 30 Oct 2010 19:15:18 +0000 (20:15 +0100)
Calling a subref whose value was PL_sv_yes, and without args,
failed to pop an entry off the mark stack

pp_hot.c
t/op/sub.t

index f4d79dc..7f80fa5 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2764,6 +2764,8 @@ PP(pp_entersub)
        if (sv == &PL_sv_yes) {         /* unfound import, ignore */
            if (hasargs)
                SP = PL_stack_base + POPMARK;
+           else
+               (void)POPMARK;
            RETURN;
        }
        SvGETMAGIC(sv);
index b6f90f4..5bd4508 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan( tests => 4 );
+plan( tests => 8 );
 
 sub empty_sub {}
 
@@ -17,3 +17,26 @@ is(scalar(@test), 0, 'Didnt return anything');
 @test = empty_sub(1,2,3);
 is(scalar(@test), 0, 'Didnt return anything');
 
+# RT #63790:  calling PL_sv_yes as a sub is special-cased to silently
+# return (so Foo->import() silently fails if import() doesn't exist),
+# But make sure it correctly pops the stack and mark stack before returning.
+
+{
+    my @a;
+    push @a, 4, 5, main->import(6,7);
+    ok(eq_array(\@a, [4,5]), "import with args");
+
+    @a = ();
+    push @a, 14, 15, main->import;
+    ok(eq_array(\@a, [14,15]), "import without args");
+
+    my $x = 1;
+
+    @a = ();
+    push @a, 24, 25, &{$x == $x}(26,27);
+    ok(eq_array(\@a, [24,25]), "yes with args");
+
+    @a = ();
+    push @a, 34, 35, &{$x == $x};
+    ok(eq_array(\@a, [34,35]), "yes without args");
+}