RT#76661: work properly in a taintperl environment
Karen Etheridge [Tue, 10 Sep 2013 23:00:30 +0000 (16:00 -0700)]
active_paths() now checks each entry in PERL_LOCAL_LIB_ROOT against @INC to be
sure that everything in PERL5LIB really did make it into @INC (taintperl
doesn't add to @INC automatically), so using perl -T -Mlocal::lib=dir
actually adds dir to @INC in all cases.

Changes
lib/local/lib.pm
t/taint-mode.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index 5551806..7fc60dc 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,9 @@
 Revision history for local::lib
 
+        - now handling using -Mlocal::lib in a taintperl environment, by
+          ensuring that all libs in PERL_LOCAL_LIB_ROOT are properly added to
+          @INC (RT#76661, Karen Etheridge)
+
 1.008011   2013-07-26
         - skip CPAN workaround if running via cpanminus  (miyagawa, RT#85731)
 
index 440757a..24cab90 100644 (file)
@@ -443,7 +443,14 @@ sub active_paths {
   my ($class) = @_;
 
   return () unless defined $ENV{PERL_LOCAL_LIB_ROOT};
-  return grep { $_ ne '' } split /\Q$Config{path_sep}/, $ENV{PERL_LOCAL_LIB_ROOT};
+
+  return grep {
+    # screen out entries that aren't actually reflected in @INC
+    my $active_ll = $class->install_base_perl_path($_);
+    grep { $_ eq $active_ll } @INC
+  }
+  grep { $_ ne '' }
+  split /\Q$Config{path_sep}\E/, $ENV{PERL_LOCAL_LIB_ROOT};
 }
 
 sub build_deactivate_environment_vars_for {
@@ -857,7 +864,8 @@ L</build_environment_vars_for>.
 =back
 
 Returns a list of active C<local::lib> paths, according to the
-C<PERL_LOCAL_LIB_ROOT> environment variable.
+C<PERL_LOCAL_LIB_ROOT> environment variable and verified against
+what is really in C<@INC>.
 
 =head2 install_base_perl_path
 
diff --git a/t/taint-mode.t b/t/taint-mode.t
new file mode 100644 (file)
index 0000000..f1a547f
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# t/taint-mode.t: checks that local::lib sets up @INC correctly when
+# included in a script that has taint mode on, and is executing in an
+# environment in which local::lib has already been loaded.
+#
+
+use strict;
+use warnings;
+use Test::More;
+use File::Temp qw(tempdir tempfile);
+use Cwd;
+
+plan tests => 1;
+
+# Setup temp dir to serve as local lib
+my $dir1 = tempdir('test_local_lib-XXXXX', DIR => Cwd::abs_path('t'), CLEANUP => 1);
+
+# Set up local::lib environment using our temp dir
+require local::lib;
+local::lib->import($dir1);
+
+# Create a script that has taint mode turned on, and tries to use a
+# local lib to the same temp dir.
+my ($fh, $filename) = tempfile('test_local_lib-XXXXX', DIR => Cwd::abs_path('t'), UNLINK => 1);
+
+print $fh <<EOM;
+#!/usr/bin/perl -T
+use strict; use warnings;
+use local::lib '$dir1';
+my \$dir1 = "$dir1";
+if (grep { \$_ =~ m{^\$dir1/} } \@INC) {
+  exit 0;
+}
+exit 1
+EOM
+close $fh;
+
+my $exit_val = system($^X, '-Ilib', '-T', $filename);
+
+is($exit_val >> 8, 0, 'test script exited with 0, local::lib dir found in @INC');