xref: /openbsd-src/gnu/usr.bin/perl/t/op/require_errors.t (revision e068048151d29f2562a32185e21a8ba885482260)
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