From: Niko Tyni <ntyni@debian.org>
Bug-Debian: http://bugs.debian.org/622817
Bug: http://rt.perl.org/rt3/Public/Bug/Display.html?id=87336
Origin: upstream, http://perl5.git.perl.org/perl.git/commitdiff/539689e74a3bcb04d29e4cd9396de91a81045b99
Subject: fix unwanted taint laundering in lc(), uc() et al.

Upstream patch ported to 5.12 by Marcela Mašláňová <mmaslano@redhat.com>

Tests modified by Niko Tyni <ntyni@debian.org> to actually fail without
the patch.


---
 pp.c         |    7 ++++++-
 t/op/taint.t |   15 ++++++++++++++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/pp.c b/pp.c
index 1c8620c..40e512a 100644
--- a/pp.c
+++ b/pp.c
@@ -3616,6 +3616,8 @@ PP(pp_ucfirst)
 	    SvCUR_set(dest, need - 1);
 	}
     }
+    if (dest != source && SvTAINTED(source))
+        SvTAINT(dest);
     SvSETMAGIC(dest);
     RETURN;
 }
@@ -3666,7 +3668,8 @@ PP(pp_uc)
 	SvUPGRADE(dest, SVt_PV);
 	d = (U8*)SvGROW(dest, min);
 	(void)SvPOK_only(dest);
-
+	if (dest != source && SvTAINTED(source))
+	    SvTAINT(dest);
 	SETs(dest);
     }
 
@@ -3835,6 +3838,8 @@ PP(pp_lc)
 	    SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
 	}
     }
+    if (dest != source && SvTAINTED(source))
+        SvTAINT(dest);
     SvSETMAGIC(dest);
     RETURN;
 }
diff --git a/t/op/taint.t b/t/op/taint.t
index 6511fa5..80ac57b 100755
--- a/t/op/taint.t
+++ b/t/op/taint.t
@@ -17,7 +17,7 @@ use Config;
 use File::Spec::Functions;
 
 BEGIN { require './test.pl'; }
-plan tests => 302;
+plan tests => 306;
 
 $| = 1;
 
@@ -1327,6 +1327,19 @@ foreach my $ord (78, 163, 256) {
 }
 
 
+{
+    # [perl #87336] lc/uc(first) failing to taint the returned string
+    my $source = "foo$TAINT";
+    my $dest = lc $source;
+    test tainted $dest, "lc(tainted) taints its return value";
+    $dest = lcfirst $source;
+    test tainted $dest, "lcfirst(tainted) taints its return value";
+    $dest = uc $source;
+    test tainted $dest, "uc(tainted) taints its return value";
+    $dest = ucfirst $source;
+    test tainted $dest, "ucfirst(tainted) taints its return value";
+}
+
 # This may bomb out with the alarm signal so keep it last
 SKIP: {
     skip "No alarm()"  unless $Config{d_alarm};
-- 
tg: (3801a1e..) fixes/casing-taint-cve-2011-1487 (depends on: upstream)
