This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
scope.c: Allow successful saving of PL_tainted
authorKarl Williamson <public@khwilliamson.com>
Wed, 14 Dec 2011 05:10:53 +0000 (22:10 -0700)
committerKarl Williamson <public@khwilliamson.com>
Thu, 15 Dec 2011 23:26:01 +0000 (16:26 -0700)
leave_scope() saves and restores PL_tainted upon entry and exit.  This
means that any attempt to save this variable on the stack will fail, as
its unstacked value will overwrite the popped one.

To counteract this, we update our saved version with the popped value.

scope.c

diff --git a/scope.c b/scope.c
index cb0e8c5..53bc9df 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -709,7 +709,7 @@ Perl_leave_scope(pTHX_ I32 base)
     register char* str;
     I32 i;
     /* Localise the effects of the TAINT_NOT inside the loop.  */
-    const bool was = PL_tainted;
+    bool was = PL_tainted;
 
     if (base < -1)
        Perl_croak(aTHX_ "panic: corrupt saved stack index");
@@ -813,6 +813,15 @@ Perl_leave_scope(pTHX_ I32 base)
        case SAVEt_BOOL:                        /* bool reference */
            ptr = SSPOPPTR;
            *(bool*)ptr = cBOOL(uv >> 8);
+
+           if (ptr == &PL_tainted) {
+               /* If we don't update <was>, to reflect what was saved on the
+                * stack for PL_tainted, then we will overwrite this attempt to
+                * restore it when we exit this routine.  Note that this won't
+                * work if this value was saved in a wider-than necessary type,
+                * such as I32 */
+               was = *(bool*)ptr;
+           }
            break;
        case SAVEt_I32_SMALL:
            ptr = SSPOPPTR;