From: Chip Salzenberg Date: Fri, 25 Apr 1997 01:55:09 +0000 (+1200) Subject: Handle tainted values in lists returned from subs, evals X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=a1f49e722e7e3f3a14f81e8dd51de229003f2378;p=p5sagit%2Fp5-mst-13.2.git Handle tainted values in lists returned from subs, evals --- diff --git a/pp_ctl.c b/pp_ctl.c index b05e13f..009d636 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -1316,6 +1316,7 @@ PP(pp_leaveloop) mark = newsp; POPLOOP1(cx); /* Delay POPLOOP2 until stack values are safe */ + TAINT_NOT; if (gimme == G_VOID) ; /* do nothing */ else if (gimme == G_SCALAR) { @@ -1325,8 +1326,10 @@ PP(pp_leaveloop) *++newsp = &sv_undef; } else { - while (mark < SP) + while (mark < SP) { *++newsp = sv_mortalcopy(*++mark); + TAINT_NOT; /* Each item is independent */ + } } SP = newsp; PUTBACK; @@ -1389,6 +1392,7 @@ PP(pp_return) DIE("panic: return"); } + TAINT_NOT; if (gimme == G_SCALAR) { if (MARK < SP) *++newsp = (popsub2 && SvTEMP(*SP)) @@ -1397,9 +1401,11 @@ PP(pp_return) *++newsp = &sv_undef; } else if (gimme == G_ARRAY) { - while (++MARK <= SP) + while (++MARK <= SP) { *++newsp = (popsub2 && SvTEMP(*MARK)) ? *MARK : sv_mortalcopy(*MARK); + TAINT_NOT; /* Each item is independent */ + } } stack_sp = newsp; @@ -1461,6 +1467,7 @@ PP(pp_last) DIE("panic: last"); } + TAINT_NOT; if (gimme == G_SCALAR) { if (MARK < SP) *++newsp = ((pop2 == CXt_SUB) && SvTEMP(*SP)) @@ -1469,9 +1476,11 @@ PP(pp_last) *++newsp = &sv_undef; } else if (gimme == G_ARRAY) { - while (++MARK <= SP) + while (++MARK <= SP) { *++newsp = ((pop2 == CXt_SUB) && SvTEMP(*MARK)) ? *MARK : sv_mortalcopy(*MARK); + TAINT_NOT; /* Each item is independent */ + } } SP = newsp; PUTBACK; @@ -2326,6 +2335,7 @@ PP(pp_leaveeval) POPEVAL(cx); retop = pop_return(); + TAINT_NOT; if (gimme == G_VOID) MARK = newsp; else if (gimme == G_SCALAR) { @@ -2342,10 +2352,13 @@ PP(pp_leaveeval) } } else { - for (mark = newsp + 1; mark <= SP; mark++) - if (!(SvFLAGS(*mark) & SVs_TEMP)) + /* in case LEAVE wipes old return values */ + for (mark = newsp + 1; mark <= SP; mark++) { + if (!(SvFLAGS(*mark) & SVs_TEMP)) { *mark = sv_mortalcopy(*mark); - /* in case LEAVE wipes old return values */ + TAINT_NOT; /* Each item is independent */ + } + } } curpm = newpm; /* Don't pop $1 et al till now */ @@ -2406,6 +2419,7 @@ PP(pp_leavetry) POPEVAL(cx); pop_return(); + TAINT_NOT; if (gimme == G_VOID) SP = newsp; else if (gimme == G_SCALAR) { @@ -2423,10 +2437,13 @@ PP(pp_leavetry) SP = MARK; } else { - for (mark = newsp + 1; mark <= SP; mark++) - if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) + /* in case LEAVE wipes old return values */ + for (mark = newsp + 1; mark <= SP; mark++) { + if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) { *mark = sv_mortalcopy(*mark); - /* in case LEAVE wipes old return values */ + TAINT_NOT; /* Each item is independent */ + } + } } curpm = newpm; /* Don't pop $1 et al till now */ diff --git a/pp_hot.c b/pp_hot.c index 8a301e5..d8b1976 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -602,8 +602,10 @@ PP(pp_aassign) if (op->op_private & OPpASSIGN_COMMON) { for (relem = firstrelem; relem <= lastrelem; relem++) { /*SUPPRESS 560*/ - if (sv = *relem) + if (sv = *relem) { + TAINT_NOT; /* Each item is independent */ *relem = sv_mortalcopy(sv); + } } } @@ -1313,6 +1315,7 @@ PP(pp_leave) gimme = G_SCALAR; } + TAINT_NOT; if (gimme == G_VOID) SP = newsp; else if (gimme == G_SCALAR) { @@ -1329,10 +1332,13 @@ PP(pp_leave) SP = MARK; } else if (gimme == G_ARRAY) { - for (mark = newsp + 1; mark <= SP; mark++) - if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) + /* in case LEAVE wipes old return values */ + for (mark = newsp + 1; mark <= SP; mark++) { + if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) { *mark = sv_mortalcopy(*mark); - /* in case LEAVE wipes old return values */ + TAINT_NOT; /* Each item is independent */ + } + } } curpm = newpm; /* Don't pop $1 et al till now */ @@ -1693,6 +1699,7 @@ PP(pp_leavesub) POPBLOCK(cx,newpm); POPSUB1(cx); /* Delay POPSUB2 until stack values are safe */ + TAINT_NOT; if (gimme == G_SCALAR) { MARK = newsp + 1; if (MARK <= SP) @@ -1705,8 +1712,10 @@ PP(pp_leavesub) } else if (gimme == G_ARRAY) { for (MARK = newsp + 1; MARK <= SP; MARK++) { - if (!SvTEMP(*MARK)) + if (!SvTEMP(*MARK)) { *MARK = sv_mortalcopy(*MARK); + TAINT_NOT; /* Each item is independent */ + } } } PUTBACK; diff --git a/t/op/taint.t b/t/op/taint.t index 81d698a..8639fd6 100755 --- a/t/op/taint.t +++ b/t/op/taint.t @@ -79,7 +79,7 @@ print PROG 'print "@ARGV\n"', "\n"; close PROG; my $echo = "$Invoke_Perl $ECHO"; -print "1..112\n"; +print "1..136\n"; # First, let's make sure that Perl is checking the dangerous # environment variables. Maybe they aren't set yet, so we'll @@ -469,3 +469,39 @@ print "1..112\n"; test 111, tainted($bar--); test 112, $bar == 0; } + +# Test assignment and return of lists +{ + my @foo = ("A", "tainted" . $TAINT, "B"); + test 113, not tainted $foo[0]; + test 114, tainted $foo[1]; + test 115, not tainted $foo[2]; + my @bar = @foo; + test 116, not tainted $bar[0]; + test 117, tainted $bar[1]; + test 118, not tainted $bar[2]; + my @baz = eval { "A", "tainted" . $TAINT, "B" }; + test 119, not tainted $baz[0]; + test 120, tainted $baz[1]; + test 121, not tainted $baz[2]; + my @plugh = eval q[ "A", "tainted" . $TAINT, "B" ]; + test 122, not tainted $plugh[0]; + test 123, tainted $plugh[1]; + test 124, not tainted $plugh[2]; + my $nautilus = sub { "A", "tainted" . $TAINT, "B" }; + test 125, not tainted ((&$nautilus)[0]); + test 126, tainted ((&$nautilus)[1]); + test 127, not tainted ((&$nautilus)[2]); + my @xyzzy = &$nautilus; + test 128, not tainted $xyzzy[0]; + test 129, tainted $xyzzy[1]; + test 130, not tainted $xyzzy[2]; + my $red_october = sub { return "A", "tainted" . $TAINT, "B" }; + test 131, not tainted ((&$red_october)[0]); + test 132, tainted ((&$red_october)[1]); + test 133, not tainted ((&$red_october)[2]); + my @corge = &$red_october; + test 134, not tainted $corge[0]; + test 135, tainted $corge[1]; + test 136, not tainted $corge[2]; +}