1#!./perl 2# 3# Tests for Perl run-time environment variable settings 4# 5# $PERL5OPT, $PERL5LIB, etc. 6 7BEGIN { 8 chdir 't' if -d 't'; 9 @INC = '../lib'; 10 require Config; import Config; 11 require './test.pl'; 12 skip_all_without_config('d_fork'); 13} 14 15plan tests => 106; 16 17my $STDOUT = tempfile(); 18my $STDERR = tempfile(); 19my $PERL = './perl'; 20my $FAILURE_CODE = 119; 21 22delete $ENV{PERLLIB}; 23delete $ENV{PERL5LIB}; 24delete $ENV{PERL5OPT}; 25delete $ENV{PERL_USE_UNSAFE_INC}; 26 27sub try { 28 my ($env, $args, $stdout, $stderr) = @_; 29 my ($actual_stdout, $actual_stderr) = runperl_and_capture($env, $args); 30 local $::Level = $::Level + 1; 31 my @envpairs = (); 32 for my $k (sort keys %$env) { 33 push @envpairs, "$k => $env->{$k}"; 34 } 35 my $label = join(',' => (@envpairs, @$args)); 36 if (ref $stdout) { 37 ok ( $actual_stdout =~/$stdout/, $label . ' stdout' ); 38 } else { 39 is ( $actual_stdout, $stdout, $label . ' stdout' ); 40 } 41 if (ref $stderr) { 42 ok ( $actual_stderr =~/$stderr/, $label . ' stderr' ); 43 } else { 44 is ( $actual_stderr, $stderr, $label . ' stderr' ); 45 } 46} 47 48# PERL5OPT Command-line options (switches). Switches in 49# this variable are taken as if they were on 50# every Perl command line. Only the -[DIMUdmtw] 51# switches are allowed. When running taint 52# checks (because the program was running setuid 53# or setgid, or the -T switch was used), this 54# variable is ignored. If PERL5OPT begins with 55# -T, tainting will be enabled, and any 56# subsequent options ignored. 57 58try({PERL5OPT => '-w'}, ['-e', 'print $::x'], 59 "", 60 qq{Name "main::x" used only once: possible typo at -e line 1.\nUse of uninitialized value \$x in print at -e line 1.\n}); 61 62try({PERL5OPT => '-Mstrict'}, ['-I../lib', '-e', 'print $::x'], 63 "", ""); 64 65try({PERL5OPT => '-Mstrict'}, ['-I../lib', '-e', 'print $x'], 66 "", 67 qq{Global symbol "\$x" requires explicit package name (did you forget to declare "my \$x"?) at -e line 1.\nExecution of -e aborted due to compilation errors.\n}); 68 69# Fails in 5.6.0 70try({PERL5OPT => '-Mstrict -w'}, ['-I../lib', '-e', 'print $x'], 71 "", 72 qq{Global symbol "\$x" requires explicit package name (did you forget to declare "my \$x"?) at -e line 1.\nExecution of -e aborted due to compilation errors.\n}); 73 74# Fails in 5.6.0 75try({PERL5OPT => '-w -Mstrict'}, ['-I../lib', '-e', 'print $::x'], 76 "", 77 <<ERROR 78Name "main::x" used only once: possible typo at -e line 1. 79Use of uninitialized value \$x in print at -e line 1. 80ERROR 81 ); 82 83# Fails in 5.6.0 84try({PERL5OPT => '-w -Mstrict'}, ['-I../lib', '-e', 'print $::x'], 85 "", 86 <<ERROR 87Name "main::x" used only once: possible typo at -e line 1. 88Use of uninitialized value \$x in print at -e line 1. 89ERROR 90 ); 91 92try({PERL5OPT => '-MExporter'}, ['-I../lib', '-e0'], 93 "", 94 ""); 95 96# Fails in 5.6.0 97try({PERL5OPT => '-MExporter -MExporter'}, ['-I../lib', '-e0'], 98 "", 99 ""); 100 101try({PERL5OPT => '-Mstrict -Mwarnings'}, 102 ['-I../lib', '-e', 'print "ok" if $INC{"strict.pm"} and $INC{"warnings.pm"}'], 103 "ok", 104 ""); 105 106open my $fh, ">", "tmpOooof.pm" or die "Can't write tmpOooof.pm: $!"; 107print $fh "package tmpOooof; 1;\n"; 108close $fh; 109END { 1 while unlink "tmpOooof.pm" } 110 111try({PERL5OPT => '-I. -MtmpOooof'}, 112 ['-e', 'print "ok" if $INC{"tmpOooof.pm"} eq "tmpOooof.pm"'], 113 "ok", 114 ""); 115 116try({PERL5OPT => '-I./ -MtmpOooof'}, 117 ['-e', 'print "ok" if $INC{"tmpOooof.pm"} eq "tmpOooof.pm"'], 118 "ok", 119 ""); 120 121try({PERL5OPT => '-w -w'}, 122 ['-e', 'print $ENV{PERL5OPT}'], 123 '-w -w', 124 ''); 125 126SKIP: { 127 if (exists($Config{taint_support}) && !$Config{taint_support}) { 128 skip("built without taint support", 2); 129 } 130 try({PERL5OPT => '-t'}, 131 ['-e', 'print ${^TAINT}'], 132 '-1', 133 ''); 134} 135 136try({PERL5OPT => '-W'}, 137 ['-I../lib','-e', 'local $^W = 0; no warnings; print $x'], 138 '', 139 <<ERROR 140Name "main::x" used only once: possible typo at -e line 1. 141Use of uninitialized value \$x in print at -e line 1. 142ERROR 143); 144 145try({PERLLIB => "foobar$Config{path_sep}42"}, 146 ['-e', 'print grep { $_ eq "foobar" } @INC'], 147 'foobar', 148 ''); 149 150try({PERLLIB => "foobar$Config{path_sep}42"}, 151 ['-e', 'print grep { $_ eq "42" } @INC'], 152 '42', 153 ''); 154 155try({PERL5LIB => "foobar$Config{path_sep}42"}, 156 ['-e', 'print grep { $_ eq "foobar" } @INC'], 157 'foobar', 158 ''); 159 160try({PERL5LIB => "foobar$Config{path_sep}42"}, 161 ['-e', 'print grep { $_ eq "42" } @INC'], 162 '42', 163 ''); 164 165try({PERL5LIB => "foo", 166 PERLLIB => "bar"}, 167 ['-e', 'print grep { $_ eq "foo" } @INC'], 168 'foo', 169 ''); 170 171try({PERL5LIB => "foo", 172 PERLLIB => "bar"}, 173 ['-e', 'print grep { $_ eq "bar" } @INC'], 174 '', 175 ''); 176 177SKIP: 178{ 179 skip "NO_PERL_HASH_SEED_DEBUG set", 4 180 if $Config{ccflags} =~ /-DNO_PERL_HASH_SEED_DEBUG\b/; 181 182 try({PERL_HASH_SEED_DEBUG => 1}, 183 ['-e','1'], 184 '', 185 qr/HASH_FUNCTION =/); 186 187 try({PERL_HASH_SEED_DEBUG => 1}, 188 ['-e','1'], 189 '', 190 qr/HASH_SEED =/); 191} 192 193SKIP: 194{ 195 skip "NO_PERL_HASH_ENV or NO_PERL_HASH_SEED_DEBUG set", 16 196 if $Config{ccflags} =~ /-DNO_PERL_HASH_ENV\b/ || 197 $Config{ccflags} =~ /-DNO_PERL_HASH_SEED_DEBUG\b/; 198 199 # special case, seed "0" implies disabled hash key traversal randomization 200 try({PERL_HASH_SEED_DEBUG => 1, PERL_HASH_SEED => "0"}, 201 ['-e','1'], 202 '', 203 qr/PERTURB_KEYS = 0/); 204 205 # check that setting it to a different value with the same logical value 206 # triggers the normal "deterministic mode". 207 try({PERL_HASH_SEED_DEBUG => 1, PERL_HASH_SEED => "0x0"}, 208 ['-e','1'], 209 '', 210 qr/PERTURB_KEYS = 2/); 211 212 try({PERL_HASH_SEED_DEBUG => 1, PERL_PERTURB_KEYS => "0"}, 213 ['-e','1'], 214 '', 215 qr/PERTURB_KEYS = 0/); 216 217 try({PERL_HASH_SEED_DEBUG => 1, PERL_PERTURB_KEYS => "1"}, 218 ['-e','1'], 219 '', 220 qr/PERTURB_KEYS = 1/); 221 222 try({PERL_HASH_SEED_DEBUG => 1, PERL_PERTURB_KEYS => "2"}, 223 ['-e','1'], 224 '', 225 qr/PERTURB_KEYS = 2/); 226 227 try({PERL_HASH_SEED_DEBUG => 1, PERL_HASH_SEED => "12345678"}, 228 ['-e','1'], 229 '', 230 qr/HASH_SEED = 0x12345678/); 231 232 try({PERL_HASH_SEED_DEBUG => 1, PERL_HASH_SEED => "12"}, 233 ['-e','1'], 234 '', 235 qr/HASH_SEED = 0x12000000/); 236 237 try({PERL_HASH_SEED_DEBUG => 1, PERL_HASH_SEED => "123456789"}, 238 ['-e','1'], 239 '', 240 qr/HASH_SEED = 0x12345678/); 241 242 # Test that PERL_PERTURB_KEYS works as expected. We check that we get the same 243 # results if we use PERL_PERTURB_KEYS = 0 or 2 and we reuse the seed from previous run. 244 my @print_keys = ( '-e', '@_{"A".."Z"}=(); print keys %_'); 245 for my $mode ( 0,1, 2 ) { # disabled and deterministic respectively 246 my %base_opts = ( PERL_PERTURB_KEYS => $mode, PERL_HASH_SEED_DEBUG => 1 ), 247 my ($out, $err) = runperl_and_capture( { %base_opts }, [ @print_keys ]); 248 if ($err=~/HASH_SEED = (0x[a-f0-9]+)/) { 249 my $seed = $1; 250 my($out2, $err2) = runperl_and_capture( { %base_opts, PERL_HASH_SEED => $seed }, [ @print_keys ]); 251 if ( $mode == 1 ) { 252 isnt ($out,$out2,"PERL_PERTURB_KEYS = $mode results in different key order with the same key"); 253 } else { 254 is ($out,$out2,"PERL_PERTURB_KEYS = $mode allows one to recreate a random hash"); 255 } 256 is ($err,$err2,"Got the same debug output when we set PERL_HASH_SEED and PERL_PERTURB_KEYS"); 257 } 258 } 259} 260 261# Tests for S_incpush_use_sep(): 262 263my @dump_inc = ('-e', 'print "$_\n" foreach @INC'); 264 265my ($out, $err) = runperl_and_capture({}, [@dump_inc]); 266 267is ($err, '', 'No errors when determining @INC'); 268 269my @default_inc = split /\n/, $out; 270 271SKIP: { 272 skip_if_miniperl("under miniperl", 3); 273if ($Config{default_inc_excludes_dot}) { 274 ok !(grep { $_ eq '.' } @default_inc), '. is not in @INC'; 275 ($out, $err) = runperl_and_capture({ PERL_USE_UNSAFE_INC => 1 }, [@dump_inc]); 276 277 is ($err, '', 'No errors when determining unsafe @INC'); 278 279 my @unsafe_inc = split /\n/, $out; 280 281 ok (eq_array([@unsafe_inc], [@default_inc, '.']), '. last in unsafe @INC') 282 or diag 'Unsafe @INC is: ', @unsafe_inc; 283} 284else { 285 is ($default_inc[-1], '.', '. is last in @INC'); 286 skip('Not testing unsafe @INC when it includes . by default', 2); 287} 288} 289 290my $sep = $Config{path_sep}; 291foreach (['nothing', ''], 292 ['something', 'zwapp', 'zwapp'], 293 ['two things', "zwapp${sep}bam", 'zwapp', 'bam'], 294 ['two things, ::', "zwapp${sep}${sep}bam", 'zwapp', 'bam'], 295 [': at start', "${sep}zwapp", 'zwapp'], 296 [': at end', "zwapp${sep}", 'zwapp'], 297 [':: sandwich ::', "${sep}${sep}zwapp${sep}${sep}", 'zwapp'], 298 [':', "${sep}"], 299 ['::', "${sep}${sep}"], 300 [':::', "${sep}${sep}${sep}"], 301 ['two things and :', "zwapp${sep}bam${sep}", 'zwapp', 'bam'], 302 [': and two things', "${sep}zwapp${sep}bam", 'zwapp', 'bam'], 303 [': two things :', "${sep}zwapp${sep}bam${sep}", 'zwapp', 'bam'], 304 ['three things', "zwapp${sep}bam${sep}${sep}owww", 305 'zwapp', 'bam', 'owww'], 306 ) { 307 my ($name, $lib, @expect) = @$_; 308 push @expect, @default_inc; 309 310 ($out, $err) = runperl_and_capture({PERL5LIB => $lib}, [@dump_inc]); 311 312 is ($err, '', "No errors when determining \@INC for $name"); 313 314 my @inc = split /\n/, $out; 315 316 is (scalar @inc, scalar @expect, 317 "expected number of elements in \@INC for $name"); 318 319 is ("@inc", "@expect", "expected elements in \@INC for $name"); 320} 321 322# PERL5LIB tests with included arch directories still missing 323