1898184e3Ssthen#!perl 2898184e3Ssthen 3898184e3SsthenBEGIN { 4b8851fccSafresh1 chdir 't' if -d 't'; 5898184e3Ssthen require './test.pl'; 69f11ffb7Safresh1 set_up_inc( qw(../lib) ); 7898184e3Ssthen} 8898184e3Ssthen 9b8851fccSafresh1use strict; 10b8851fccSafresh1use warnings; 11b8851fccSafresh1 12*e0680481Safresh1plan(tests => 73); 13*e0680481Safresh1 14*e0680481Safresh1 15*e0680481Safresh1# Dedupe @INC. In a future patch we /may/ refuse to process items 16*e0680481Safresh1# more than once and deduping here will prevent the tests from failing 17*e0680481Safresh1# should we make that change. 18*e0680481Safresh1my %seen; @INC = grep {!$seen{$_}++} @INC; 19898184e3Ssthen 20898184e3Ssthenmy $nonfile = tempfile(); 21898184e3Ssthen 2291f110e0Safresh1# The tests for ' ' and '.h' never did fail, but previously the error reporting 2391f110e0Safresh1# code would read memory before the start of the SV's buffer 2491f110e0Safresh1 2591f110e0Safresh1for my $file ($nonfile, ' ') { 26898184e3Ssthen eval { 2791f110e0Safresh1 require $file; 28898184e3Ssthen }; 29898184e3Ssthen 30*e0680481Safresh1 like $@, qr/^Can't locate $file in \@INC \(\@INC[\w ]+: \Q@INC\E\) at/, 3191f110e0Safresh1 "correct error message for require '$file'"; 3291f110e0Safresh1} 3391f110e0Safresh1 349f11ffb7Safresh1# Check that the "(you may need to install..) hint is included in the 359f11ffb7Safresh1# error message where (and only where) appropriate. 369f11ffb7Safresh1# 379f11ffb7Safresh1# Basically the hint should be issued for any filename where converting 389f11ffb7Safresh1# back from Foo/Bar.pm to Foo::Bar gives you a legal bare word which could 399f11ffb7Safresh1# follow "require" in source code. 4091f110e0Safresh1 419f11ffb7Safresh1{ 429f11ffb7Safresh1 439f11ffb7Safresh1 # may be any letter of an identifier 449f11ffb7Safresh1 my $I = "\x{393}"; # "\N{GREEK CAPITAL LETTER GAMMA}" 459f11ffb7Safresh1 # Continuation char: may only be 2nd+ letter of an identifier 469f11ffb7Safresh1 my $C = "\x{387}"; # "\N{GREEK ANO TELEIA}" 479f11ffb7Safresh1 489f11ffb7Safresh1 for my $test_data ( 499f11ffb7Safresh1 # thing to require pathname in err mesg err includes hint? 509f11ffb7Safresh1 [ "No::Such::Module1", "No/Such/Module1.pm", 1 ], 519f11ffb7Safresh1 [ "'No/Such/Module1.pm'", "No/Such/Module1.pm", 1 ], 529f11ffb7Safresh1 [ "_No::Such::Module1", "_No/Such/Module1.pm", 1 ], 539f11ffb7Safresh1 [ "'_No/Such/Module1.pm'", "_No/Such/Module1.pm", 1 ], 549f11ffb7Safresh1 [ "'No/Such./Module.pm'", "No/Such./Module.pm", 0 ], 559f11ffb7Safresh1 [ "No::1Such::Module", "No/1Such/Module.pm", 1 ], 569f11ffb7Safresh1 [ "'No/1Such/Module.pm'", "No/1Such/Module.pm", 1 ], 579f11ffb7Safresh1 [ "1No::Such::Module", undef, 0 ], 589f11ffb7Safresh1 [ "'1No/Such/Module.pm'", "1No/Such/Module.pm", 0 ], 599f11ffb7Safresh1 609f11ffb7Safresh1 # utf8 variants 619f11ffb7Safresh1 [ "No::Such${I}::Module1", "No/Such${I}/Module1.pm", 1 ], 629f11ffb7Safresh1 [ "'No/Such${I}/Module1.pm'", "No/Such${I}/Module1.pm", 1 ], 639f11ffb7Safresh1 [ "_No::Such${I}::Module1", "_No/Such${I}/Module1.pm", 1 ], 649f11ffb7Safresh1 [ "'_No/Such${I}/Module1.pm'", "_No/Such${I}/Module1.pm", 1 ], 659f11ffb7Safresh1 [ "'No/Such${I}./Module.pm'", "No/Such${I}./Module.pm", 0 ], 669f11ffb7Safresh1 [ "No::1Such${I}::Module", "No/1Such${I}/Module.pm", 1 ], 679f11ffb7Safresh1 [ "'No/1Such${I}/Module.pm'", "No/1Such${I}/Module.pm", 1 ], 689f11ffb7Safresh1 [ "1No::Such${I}::Module", undef, 0 ], 699f11ffb7Safresh1 [ "'1No/Such${I}/Module.pm'", "1No/Such${I}/Module.pm", 0 ], 709f11ffb7Safresh1 719f11ffb7Safresh1 # utf8 with continuation char in 1st position 729f11ffb7Safresh1 [ "No::${C}Such::Module1", undef, 0 ], 739f11ffb7Safresh1 [ "'No/${C}Such/Module1.pm'", "No/${C}Such/Module1.pm", 0 ], 749f11ffb7Safresh1 [ "_No::${C}Such::Module1", undef, 0 ], 759f11ffb7Safresh1 [ "'_No/${C}Such/Module1.pm'", "_No/${C}Such/Module1.pm", 0 ], 769f11ffb7Safresh1 [ "'No/${C}Such./Module.pm'", "No/${C}Such./Module.pm", 0 ], 779f11ffb7Safresh1 [ "No::${C}1Such::Module", undef, 0 ], 789f11ffb7Safresh1 [ "'No/${C}1Such/Module.pm'", "No/${C}1Such/Module.pm", 0 ], 799f11ffb7Safresh1 [ "1No::${C}Such::Module", undef, 0 ], 809f11ffb7Safresh1 [ "'1No/${C}Such/Module.pm'", "1No/${C}Such/Module.pm", 0 ], 819f11ffb7Safresh1 829f11ffb7Safresh1 ) { 839f11ffb7Safresh1 my ($require_arg, $err_path, $has_hint) = @$test_data; 849f11ffb7Safresh1 859f11ffb7Safresh1 my $exp; 869f11ffb7Safresh1 if (defined $err_path) { 879f11ffb7Safresh1 $exp = "Can't locate $err_path in \@INC"; 889f11ffb7Safresh1 if ($has_hint) { 899f11ffb7Safresh1 my $hint = $err_path; 909f11ffb7Safresh1 $hint =~ s{/}{::}g; 919f11ffb7Safresh1 $hint =~ s/\.pm$//; 929f11ffb7Safresh1 $exp .= " (you may need to install the $hint module)"; 939f11ffb7Safresh1 } 94*e0680481Safresh1 $exp .= " (\@INC entries checked: @INC) at"; 959f11ffb7Safresh1 } 969f11ffb7Safresh1 else { 979f11ffb7Safresh1 # undef implies a require which doesn't compile, 989f11ffb7Safresh1 # rather than one which triggers a run-time error. 999f11ffb7Safresh1 # We'll set exp to a suitable value later; 1009f11ffb7Safresh1 $exp = ""; 1019f11ffb7Safresh1 } 1029f11ffb7Safresh1 1039f11ffb7Safresh1 my $err; 1049f11ffb7Safresh1 { 1059f11ffb7Safresh1 no warnings qw(syntax utf8); 1069f11ffb7Safresh1 if ($require_arg =~ /[^\x00-\xff]/) { 1079f11ffb7Safresh1 eval "require $require_arg"; 1089f11ffb7Safresh1 $err = $@; 1099f11ffb7Safresh1 utf8::decode($err); 1109f11ffb7Safresh1 } 1119f11ffb7Safresh1 else { 1129f11ffb7Safresh1 eval "require $require_arg"; 1139f11ffb7Safresh1 $err = $@; 1149f11ffb7Safresh1 } 1159f11ffb7Safresh1 } 1169f11ffb7Safresh1 1179f11ffb7Safresh1 for ($err, $exp, $require_arg) { 1189f11ffb7Safresh1 s/([^\x00-\xff])/sprintf"\\x{%x}",ord($1)/ge; 1199f11ffb7Safresh1 } 1209f11ffb7Safresh1 if (length $exp) { 1219f11ffb7Safresh1 $exp = qr/^\Q$exp\E/; 1229f11ffb7Safresh1 } 1239f11ffb7Safresh1 else { 1249f11ffb7Safresh1 $exp = qr/syntax error at|Unrecognized character/; 1259f11ffb7Safresh1 } 1269f11ffb7Safresh1 like $err, $exp, 1279f11ffb7Safresh1 "err for require $require_arg"; 1289f11ffb7Safresh1 } 1299f11ffb7Safresh1} 1309f11ffb7Safresh1 1319f11ffb7Safresh1 1329f11ffb7Safresh1 1339f11ffb7Safresh1eval "require ::$nonfile"; 1349f11ffb7Safresh1 1359f11ffb7Safresh1like $@, qr/^Bareword in require must not start with a double-colon:/, 1369f11ffb7Safresh1 "correct error message for require ::$nonfile"; 137898184e3Ssthen 138898184e3Sstheneval { 139898184e3Ssthen require "$nonfile.ph"; 140898184e3Ssthen}; 141898184e3Ssthen 142*e0680481Safresh1like $@, qr/^Can't locate $nonfile\.ph in \@INC \(did you run h2ph\?\) \(\@INC[\w ]+: @INC\) at/; 143898184e3Ssthen 14491f110e0Safresh1for my $file ("$nonfile.h", ".h") { 145898184e3Ssthen eval { 14691f110e0Safresh1 require $file 147898184e3Ssthen }; 148898184e3Ssthen 149*e0680481Safresh1 like $@, qr/^Can't locate \Q$file\E in \@INC \(change \.h to \.ph maybe\?\) \(did you run h2ph\?\) \(\@INC[\w ]+: @INC\) at/, 15091f110e0Safresh1 "correct error message for require '$file'"; 15191f110e0Safresh1} 15291f110e0Safresh1 15391f110e0Safresh1for my $file ("$nonfile.ph", ".ph") { 15491f110e0Safresh1 eval { 15591f110e0Safresh1 require $file 15691f110e0Safresh1 }; 15791f110e0Safresh1 158*e0680481Safresh1 like $@, qr/^Can't locate \Q$file\E in \@INC \(did you run h2ph\?\) \(\@INC[\w ]+: @INC\) at/, 15991f110e0Safresh1 "correct error message for require '$file'"; 16091f110e0Safresh1} 16191f110e0Safresh1 16291f110e0Safresh1eval 'require <foom>'; 163b8851fccSafresh1like $@, qr/^<> at require-statement should be quotes at /, 'require <> error'; 16491f110e0Safresh1 16591f110e0Safresh1my $module = tempfile(); 16691f110e0Safresh1my $mod_file = "$module.pm"; 16791f110e0Safresh1 16891f110e0Safresh1open my $module_fh, ">", $mod_file or die $!; 16991f110e0Safresh1print { $module_fh } "print 1; 1;\n"; 17091f110e0Safresh1close $module_fh; 17191f110e0Safresh1 17291f110e0Safresh1chmod 0333, $mod_file; 17391f110e0Safresh1 17491f110e0Safresh1SKIP: { 17591f110e0Safresh1 skip_if_miniperl("these modules may not be available to miniperl", 2); 17691f110e0Safresh1 17791f110e0Safresh1 push @INC, '../lib'; 17891f110e0Safresh1 require Cwd; 17991f110e0Safresh1 require File::Spec::Functions; 18091f110e0Safresh1 if ($^O eq 'cygwin') { 18191f110e0Safresh1 require Win32; 18291f110e0Safresh1 } 18391f110e0Safresh1 18491f110e0Safresh1 # Going to try to switch away from root. Might not work. 18591f110e0Safresh1 # (stolen from t/op/stat.t) 18691f110e0Safresh1 my $olduid = $>; 18791f110e0Safresh1 eval { $> = 1; }; 18891f110e0Safresh1 skip "Can't test permissions meaningfully if you're superuser", 2 18991f110e0Safresh1 if ($^O eq 'cygwin' ? Win32::IsAdminUser() : $> == 0); 19091f110e0Safresh1 19191f110e0Safresh1 local @INC = "."; 19291f110e0Safresh1 eval "use $module"; 19391f110e0Safresh1 like $@, 19491f110e0Safresh1 qr<^\QCan't locate $mod_file:>, 19591f110e0Safresh1 "special error message if the file exists but can't be opened"; 19691f110e0Safresh1 19791f110e0Safresh1 SKIP: { 19891f110e0Safresh1 skip "Can't make the path absolute", 1 19991f110e0Safresh1 if !defined(Cwd::getcwd()); 20091f110e0Safresh1 20191f110e0Safresh1 my $file = File::Spec::Functions::catfile(Cwd::getcwd(), $mod_file); 20291f110e0Safresh1 eval { 20391f110e0Safresh1 require($file); 20491f110e0Safresh1 }; 20591f110e0Safresh1 like $@, 20691f110e0Safresh1 qr<^\QCan't locate $file:>, 20791f110e0Safresh1 "...even if we use a full path"; 20891f110e0Safresh1 } 20991f110e0Safresh1 21091f110e0Safresh1 # switch uid back (may not be implemented) 21191f110e0Safresh1 eval { $> = $olduid; }; 21291f110e0Safresh1} 21391f110e0Safresh1 21491f110e0Safresh11 while unlink $mod_file; 215898184e3Ssthen 216898184e3Ssthen# I can't see how to test the EMFILE case 217898184e3Ssthen# I can't see how to test the case of not displaying @INC in the message. 218898184e3Ssthen# (and does that only happen on VMS?) 2196fb12b70Safresh1 2206fb12b70Safresh1# fail and print the full filename 2216fb12b70Safresh1eval { no warnings 'syscalls'; require "strict.pm\0invalid"; }; 2226fb12b70Safresh1like $@, qr/^Can't locate strict\.pm\\0invalid: /, 'require nul check [perl #117265]'; 2236fb12b70Safresh1{ 2246fb12b70Safresh1 my $WARN; 2256fb12b70Safresh1 local $SIG{__WARN__} = sub { $WARN = shift }; 2269f11ffb7Safresh1 { 2279f11ffb7Safresh1 my $ret = do "strict.pm\0invalid"; 2289f11ffb7Safresh1 my $exc = $@; 2299f11ffb7Safresh1 my $err = $!; 2309f11ffb7Safresh1 is $ret, undef, 'do nulstring returns undef'; 2319f11ffb7Safresh1 is $exc, '', 'do nulstring clears $@'; 2329f11ffb7Safresh1 $! = $err; 2339f11ffb7Safresh1 ok $!{ENOENT}, 'do nulstring fails with ENOENT'; 2349f11ffb7Safresh1 like $WARN, qr{^Invalid \\0 character in pathname for do: strict\.pm\\0invalid at }, 'do nulstring warning'; 2359f11ffb7Safresh1 } 2369f11ffb7Safresh1 2379f11ffb7Safresh1 $WARN = ''; 2386fb12b70Safresh1 eval { require "strict.pm\0invalid"; }; 2396fb12b70Safresh1 like $WARN, qr{^Invalid \\0 character in pathname for require: strict\.pm\\0invalid at }, 'nul warning'; 2406fb12b70Safresh1 like $@, qr{^Can't locate strict\.pm\\0invalid: }, 'nul error'; 2416fb12b70Safresh1 2426fb12b70Safresh1 $WARN = ''; 2436fb12b70Safresh1 local @INC = @INC; 2449f11ffb7Safresh1 set_up_inc( "lib\0invalid" ); 2456fb12b70Safresh1 eval { require "unknown.pm" }; 2466fb12b70Safresh1 like $WARN, qr{^Invalid \\0 character in \@INC entry for require: lib\\0invalid at }, 'nul warning'; 2476fb12b70Safresh1} 2486fb12b70Safresh1eval "require strict\0::invalid;"; 2496fb12b70Safresh1like $@, qr/^syntax error at \(eval \d+\) line 1/, 'parse error with \0 in barewords module names'; 2506fb12b70Safresh1 251c0dd97bfSafresh1# Refs and globs that stringify with embedded nulls 252c0dd97bfSafresh1# These crashed from 5.20 to 5.24 [perl #128182]. 253c0dd97bfSafresh1eval { no warnings 'syscalls'; require eval "qr/\0/" }; 254c0dd97bfSafresh1like $@, qr/^Can't locate \(\?\^:\\0\):/, 255c0dd97bfSafresh1 'require ref that stringifies with embedded null'; 256c0dd97bfSafresh1eval { no strict; no warnings 'syscalls'; require *{"\0a"} }; 257c0dd97bfSafresh1like $@, qr/^Can't locate \*main::\\0a:/, 258c0dd97bfSafresh1 'require ref that stringifies with embedded null'; 2599f11ffb7Safresh1 2609f11ffb7Safresh1eval { require undef }; 2619f11ffb7Safresh1like $@, qr/^Missing or undefined argument to require /; 2629f11ffb7Safresh1 2639f11ffb7Safresh1eval { do undef }; 2649f11ffb7Safresh1like $@, qr/^Missing or undefined argument to do /; 2659f11ffb7Safresh1 2669f11ffb7Safresh1eval { require "" }; 2679f11ffb7Safresh1like $@, qr/^Missing or undefined argument to require /; 2689f11ffb7Safresh1 2699f11ffb7Safresh1eval { do "" }; 2709f11ffb7Safresh1like $@, qr/^Missing or undefined argument to do /; 2719f11ffb7Safresh1 2729f11ffb7Safresh1# non-searchable pathnames shouldn't mention @INC in the error 2739f11ffb7Safresh1 2749f11ffb7Safresh1my $nonsearch = "./no_such_file.pm"; 2759f11ffb7Safresh1 2769f11ffb7Safresh1eval "require \"$nonsearch\""; 2779f11ffb7Safresh1 2789f11ffb7Safresh1like $@, qr/^Can't locate \Q$nonsearch\E at/, 2799f11ffb7Safresh1 "correct error message for require $nonsearch"; 28056d68f1eSafresh1 28156d68f1eSafresh1{ 28256d68f1eSafresh1 # make sure require doesn't treat a non-PL_sv_undef undef as 28356d68f1eSafresh1 # success in %INC 28456d68f1eSafresh1 # GH #17428 28556d68f1eSafresh1 push @INC, "lib"; 28656d68f1eSafresh1 ok(!eval { require CannotParse; }, "should fail to load"); 28756d68f1eSafresh1 local %INC = %INC; # copies \&PL_sv_undef into a new undef 28856d68f1eSafresh1 ok(!eval { require CannotParse; }, 28956d68f1eSafresh1 "check the second attempt also fails"); 29056d68f1eSafresh1 like $@, qr/Attempt to reload/, "check we failed for the right reason"; 29156d68f1eSafresh1} 292*e0680481Safresh1 293*e0680481Safresh1{ 294*e0680481Safresh1 fresh_perl_like( 295*e0680481Safresh1 'unshift @INC, sub { sub { 0 } }; require "asdasd";', 296*e0680481Safresh1 qr/asdasd did not return a true value/, 297*e0680481Safresh1 { }, '@INC hook blocks do not cause segfault'); 298*e0680481Safresh1} 299*e0680481Safresh1 300*e0680481Safresh1{ 301*e0680481Safresh1 # make sure that modifications to %INC during an INC hooks lifetime 302*e0680481Safresh1 # don't result in us having an empty string for the cop_file. 303*e0680481Safresh1 # Older perls will output "error at line 1". 304*e0680481Safresh1 305*e0680481Safresh1 fresh_perl_like( 306*e0680481Safresh1 'use lib qq(./lib); BEGIN{ unshift @INC, ' 307*e0680481Safresh1 .'sub { if ($_[1] eq "CannotParse.pm" and !$seen++) { ' 308*e0680481Safresh1 .'eval q(require $_[1]); warn $@; my $code= qq[die qq(error)];' 309*e0680481Safresh1 .'open my $fh,"<", q(lib/Dies.pm); return $fh } } } require CannotParse;', 310*e0680481Safresh1 qr!\Asyntax error.*?^error at /loader/0x[A-Fa-f0-9]+/CannotParse\.pm line 1\.!ms, 311*e0680481Safresh1 { }, 'Inc hooks have the correct cop_file'); 312*e0680481Safresh1} 313*e0680481Safresh1{ 314*e0680481Safresh1 # this can segfault or assert prior to @INC hardening. 315*e0680481Safresh1 fresh_perl_like( 316*e0680481Safresh1 'unshift @INC, sub { *INC=["a","b"] }; ' 317*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 318*e0680481Safresh1 qr!\(\@INC[\w ]+: CODE\(0x[A-Fa-f0-9]+\) b\)!, 319*e0680481Safresh1 { }, 'INC hooks do not segfault when overwritten'); 320*e0680481Safresh1} 321*e0680481Safresh1{ 322*e0680481Safresh1 # this is the defined behavior, but in older perls the error message 323*e0680481Safresh1 # would lie and say "contains: a b", which is true in the sense that 324*e0680481Safresh1 # it is the value of @INC after the require, but not the directory 325*e0680481Safresh1 # list that was looked at. 326*e0680481Safresh1 fresh_perl_like( 327*e0680481Safresh1 '@INC = (sub { @INC=("a","b"); () }, "z"); ' 328*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 329*e0680481Safresh1 qr!\(\@INC[\w ]+: CODE\(0x[A-Fa-f0-9]+\) b\)!, 330*e0680481Safresh1 { }, 'INC hooks that overwrite @INC continue as expected (skips a and z)'); 331*e0680481Safresh1} 332*e0680481Safresh1{ 333*e0680481Safresh1 # as of 5.37.7 334*e0680481Safresh1 fresh_perl_like( 335*e0680481Safresh1 '@INC = (sub { @INC=qw(a b); undef $INC }, "z"); ' 336*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 337*e0680481Safresh1 qr!\(\@INC[\w ]+: CODE\(0x[A-Fa-f0-9]+\) a b\)!, 338*e0680481Safresh1 { }, 'INC hooks that overwrite @INC and undef $INC continue at start'); 339*e0680481Safresh1} 340*e0680481Safresh1{ 341*e0680481Safresh1 # as of 5.37.7 342*e0680481Safresh1 fresh_perl_like( 343*e0680481Safresh1 'sub CB::INCDIR { return "b", "c","d" }; ' 344*e0680481Safresh1 .'@INC = ("a",bless({},"CB"),"e");' 345*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 346*e0680481Safresh1 qr!\(\@INC[\w ]+: a CB=HASH\(0x[A-Fa-f0-9]+\) b c d e\)!, 347*e0680481Safresh1 { }, 'INCDIR works as expected'); 348*e0680481Safresh1} 349*e0680481Safresh1{ 350*e0680481Safresh1 # as of 5.37.7 351*e0680481Safresh1 fresh_perl_like( 352*e0680481Safresh1 '@INC = ("a",bless({},"CB"),"e");' 353*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 354*e0680481Safresh1 qr!Can't locate object method "INC", nor "INCDIR" nor string overload via package "CB" in object hook in \@INC!, 355*e0680481Safresh1 { }, 'Objects with no INC or INCDIR method and no overload throw an error'); 356*e0680481Safresh1} 357*e0680481Safresh1{ 358*e0680481Safresh1 # as of 5.37.7 359*e0680481Safresh1 fresh_perl_like( 360*e0680481Safresh1 'package CB { use overload q("") => sub { "Fnorble" };} @INC = ("a",bless({},"CB"),"e");' 361*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 362*e0680481Safresh1 qr!\(\@INC[\w ]+: a Fnorble e\)!, 363*e0680481Safresh1 { }, 'Objects with no INC or INCDIR method but with an overload are stringified'); 364*e0680481Safresh1} 365*e0680481Safresh1{ 366*e0680481Safresh1 # as of 5.37.7 367*e0680481Safresh1 fresh_perl_like( 368*e0680481Safresh1 'package CB { use overload q(0+) => sub { 12345 }, fallback=>1;} @INC = ("a",bless({},"CB"),"e");' 369*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 370*e0680481Safresh1 qr!\(\@INC[\w ]+: a 12345 e\)!, 371*e0680481Safresh1 { }, 'Objects with no INC or INCDIR method but with an overload with fallback are stringified'); 372*e0680481Safresh1} 373*e0680481Safresh1{ 374*e0680481Safresh1 # as of 5.37.7 375*e0680481Safresh1 fresh_perl_like( 376*e0680481Safresh1 '{package CB; use overload qw("")=>sub { "blorg"};} ' 377*e0680481Safresh1 .'@INC = ("a",bless({},"CB"),"e");' 378*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 379*e0680481Safresh1 qr!\(\@INC[\w ]+: a blorg e\)!, 380*e0680481Safresh1 { }, 'Objects with overload and no INC or INCDIR method are stringified'); 381*e0680481Safresh1} 382*e0680481Safresh1{ 383*e0680481Safresh1 # as of 5.37.7 384*e0680481Safresh1 fresh_perl_like( 385*e0680481Safresh1 '@INC = ("a",bless(sub { warn "blessed sub called" },"CB"),"e");' 386*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 387*e0680481Safresh1 qr!blessed sub called.*\(\@INC[\w ]+: a CB=CODE\(0x[a-fA-F0-9]+\) e\)!s, 388*e0680481Safresh1 { }, 'Blessed subs with no hook methods are executed'); 389*e0680481Safresh1} 390*e0680481Safresh1{ 391*e0680481Safresh1 # as of 5.37.7 392*e0680481Safresh1 fresh_perl_like( 393*e0680481Safresh1 '@INC = ("a",bless(sub { die "blessed sub called" },"CB"),"e");' 394*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 395*e0680481Safresh1 qr!INC sub hook died--halting \@INC search!s, 396*e0680481Safresh1 { }, 'Blessed subs that die produce expected extra message'); 397*e0680481Safresh1} 398*e0680481Safresh1{ 399*e0680481Safresh1 # as of 5.37.7 400*e0680481Safresh1 fresh_perl_like( 401*e0680481Safresh1 'sub CB::INC { die "bad mojo" } ' 402*e0680481Safresh1 .'@INC = ("a",bless(sub { die "blessed sub called" },"CB"),"e");' 403*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 404*e0680481Safresh1 qr!bad mojo.*INC method hook died--halting \@INC search!s, 405*e0680481Safresh1 { }, 'Blessed subs with methods call method and produce expected message'); 406*e0680481Safresh1} 407*e0680481Safresh1{ 408*e0680481Safresh1 # as of 5.37.7 409*e0680481Safresh1 fresh_perl_like( 410*e0680481Safresh1 '@INC = ("a",[bless([],"CB"),1],"e");' 411*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 412*e0680481Safresh1 qr!Can't locate object method "INC", nor "INCDIR" nor string overload via package "CB" in object in ARRAY hook in \@INC!s, 413*e0680481Safresh1 { }, 'Blessed objects with no hook methods in array form produce expected exception'); 414*e0680481Safresh1} 415*e0680481Safresh1{ 416*e0680481Safresh1 # as of 5.37.7 417*e0680481Safresh1 fresh_perl_like( 418*e0680481Safresh1 'sub CB::INCDIR { "i" } sub CB2::INCDIR { }' 419*e0680481Safresh1 .'@INC = ("a",bless(sub{"b"},"CB"),bless(sub{"c"},"CB2"),"e");' 420*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 421*e0680481Safresh1 qr!\(\@INC[\w ]+: a CB=CODE\(0x[a-fA-F0-9]+\) i CB2=CODE\(0x[a-fA-F0-9]+\) e\)!s, 422*e0680481Safresh1 { }, 'Blessed subs with INCDIR methods call INCDIR'); 423*e0680481Safresh1} 424*e0680481Safresh1{ 425*e0680481Safresh1 # as of 5.37.7 426*e0680481Safresh1 fresh_perl_like( 427*e0680481Safresh1 'sub CB::INCDIR { return @{$_[2]} }' 428*e0680481Safresh1 .'@INC = ("a",[bless([],"CB"),"b"],"c");' 429*e0680481Safresh1 .'eval "require Frobnitz" or print $@', 430*e0680481Safresh1 qr!\(\@INC[\w ]+: a ARRAY\(0x[a-fA-F0-9]+\) CB=ARRAY\(0x[a-fA-F0-9]+\) b c\)!s, 431*e0680481Safresh1 { }, 'INCDIR ref returns are stringified'); 432*e0680481Safresh1} 433