diff options
-rw-r--r-- | ext/Cwd/Cwd.xs | 3 | ||||
-rw-r--r-- | ext/Cwd/t/taint.t | 19 | ||||
-rw-r--r-- | lib/Cwd.pm | 11 |
3 files changed, 20 insertions, 13 deletions
diff --git a/ext/Cwd/Cwd.xs b/ext/Cwd/Cwd.xs index f53f6ee19e..3f7b93b231 100644 --- a/ext/Cwd/Cwd.xs +++ b/ext/Cwd/Cwd.xs @@ -222,6 +222,9 @@ PPCODE: dXSTARG; getcwd_sv(TARG); XSprePUSH; PUSHTARG; +#ifndef INCOMPLETE_TAINTS + SvTAINTED_on(TARG); +#endif } void diff --git a/ext/Cwd/t/taint.t b/ext/Cwd/t/taint.t index 74e2d65d00..3f6aa5290d 100644 --- a/ext/Cwd/t/taint.t +++ b/ext/Cwd/t/taint.t @@ -7,15 +7,18 @@ BEGIN { } use Cwd; -use Test::More tests => 2; - -# The normal kill() trick is not portable. -sub is_tainted { - return ! eval { eval("#" . substr(join("", @_), 0, 0)); 1 }; -} +use Test::More tests => 6; +use Scalar::Util qw/tainted/; my $cwd; eval { $cwd = getcwd; }; -is( $@, '', 'getcwd() does not explode under taint mode' ); -ok( is_tainted($cwd), "its return value is tainted" ); +is( $@, '', 'getcwd() does not explode under taint mode' ); +ok( tainted($cwd), "its return value is tainted" ); + +eval { $cwd = cwd; }; +is( $@, '', 'cwd() does not explode under taint mode' ); +ok( tainted($cwd), "its return value is tainted" ); +eval { $cwd = fastcwd; }; +is( $@, '', 'fastcwd() does not explode under taint mode' ); +ok( tainted($cwd), "its return value is tainted" ); diff --git a/lib/Cwd.pm b/lib/Cwd.pm index d1ad76e9f1..8b00543e1e 100644 --- a/lib/Cwd.pm +++ b/lib/Cwd.pm @@ -48,7 +48,7 @@ The cwd() is the most natural form for the current architecture. For most systems it is identical to `pwd` (but without the trailing line terminator). -Unfortunately, cwd() is B<not> taint-safe. +Taint-safe. =item fastcwd @@ -105,7 +105,8 @@ Taint-safe. A more dangerous, but potentially faster version of abs_path. -B<Not> taint-safe. +This function is B<Not> taint-safe : you can't use it in programs +that work under taint mode. =back @@ -270,9 +271,9 @@ sub fastcwd { $path = '/' . join('/', @path); if ($^O eq 'apollo') { $path = "/".$path; } # At this point $path may be tainted (if tainting) and chdir would fail. - # To be more useful we untaint it then check that we landed where we started. - $path = $1 if $path =~ /^(.*)\z/s; # untaint - CORE::chdir($path) || return undef; + # Untaint it then check that we landed where we started. + $path =~ /^(.*)\z/s # untaint + && CORE::chdir($1) or return undef; ($cdev, $cino) = stat('.'); die "Unstable directory path, current directory changed unexpectedly" if $cdev != $orig_cdev || $cino != $orig_cino; |