Skip to content

Commit 1a55cc5

Browse files
committed
t/ - INC hardening tests
These tests are pretty much all marked TODO. In the following patches we will remove the TODO as we fix the bug or implement the feature.
1 parent 8dfc361 commit 1a55cc5

File tree

2 files changed

+145
-6
lines changed

2 files changed

+145
-6
lines changed

t/op/inccode.t

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ unless (is_miniperl()) {
2121

2222
use strict;
2323

24-
plan(tests => 68 + !is_miniperl() * (3 + 14 * $can_fork));
24+
plan(tests => 68 + !is_miniperl() * (4 + 14 * $can_fork));
2525

2626
sub get_temp_fh {
2727
my $f = tempfile();
@@ -294,14 +294,18 @@ SKIP: {
294294
$$t = sub { $called ++; !1 };
295295
delete $INC{'foo.pm'}; # in case another test uses foo
296296
eval { require foo };
297-
is $INCtie::count, 2, # 2nd time for "Can't locate" -- XXX correct?
297+
{ local $::TODO = "Will be fixed in a follow up patch";
298+
is $INCtie::count, 1,
298299
'FETCH is called once on undef scalar-tied @INC elem';
300+
}
299301
is $called, 1, 'sub in scalar-tied @INC elem is called';
300302
() = "$INC[0]"; # force a fetch, so the SV is ROK
301303
$INCtie::count = 0;
302304
eval { require foo };
303-
is $INCtie::count, 2,
305+
{ local $::TODO = "Will be fixed in a follow up patch";
306+
is $INCtie::count, 1,
304307
'FETCH is called once on scalar-tied @INC elem holding ref';
308+
}
305309
is $called, 2, 'sub in scalar-tied @INC elem holding ref is called';
306310
$$t = [];
307311
$INCtie::count = 0;
@@ -311,8 +315,10 @@ SKIP: {
311315
$$t = "string";
312316
$INCtie::count = 0;
313317
eval { require foo };
314-
is $INCtie::count, 2,
318+
{ local $::TODO = "Will be fixed in a follow up patch";
319+
is $INCtie::count, 1,
315320
'FETCH called once on scalar-tied @INC elem returning string';
321+
}
316322
}
317323

318324

@@ -397,3 +403,13 @@ if ($can_fork) {
397403

398404
is ("@::bbblplast", "0 1 2 3 4 5", "All ran with a filter");
399405
}
406+
SKIP:{
407+
skip "need fork",1 unless $can_fork;
408+
local $::TODO = "Pending";
409+
fresh_perl_like('@INC=("A",bless({},"Hook"),"D"); '
410+
.'sub Hook::INCDIR { return "B","C"} '
411+
.'eval "require Frobnitz" or print $@;',
412+
qr/\(\@INC contains: A Hook=HASH\(0x[A-Fa-f0-9]+\) B C D\)/,
413+
{},
414+
"Check if INCDIR hook works as expected");
415+
}

t/op/require_errors.t

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ BEGIN {
99
use strict;
1010
use warnings;
1111

12-
plan(tests => 59);
12+
plan(tests => 71);
13+
14+
15+
# Dedupe @INC. In a future patch we /may/ refuse to process items
16+
# more than once and deduping here will prevent the tests from failing
17+
# should we make that change.
18+
my %seen; @INC = grep {!$seen{$_}++} @INC;
1319

1420
my $nonfile = tempfile();
1521

@@ -297,9 +303,126 @@ like $@, qr/^Can't locate \Q$nonsearch\E at/,
297303
# Older perls will output "error at line 1".
298304

299305
fresh_perl_like(
300-
'use lib qq(./lib); BEGIN{ unshift @INC, sub { if ($_[1] eq "CannotParse.pm" and !$seen++) { '
306+
'use lib qq(./lib); BEGIN{ unshift @INC, '
307+
.'sub { if ($_[1] eq "CannotParse.pm" and !$seen++) { '
301308
.'eval q(require $_[1]); warn $@; my $code= qq[die qq(error)];'
302309
.'open my $fh,"<", q(lib/Dies.pm); return $fh } } } require CannotParse;',
303310
qr!\Asyntax error.*?^error at /loader/0x[A-Fa-f0-9]+/CannotParse\.pm line 1\.!ms,
304311
{ }, 'Inc hooks have the correct cop_file');
305312
}
313+
{
314+
local $::TODO = "Pending segfault fix";
315+
# this can segfault or assert prior to @INC hardening.
316+
fresh_perl_like(
317+
'unshift @INC, sub { *INC=["a","b"] }; '
318+
.'eval "require Frobnitz" or print $@',
319+
qr!\(\@INC contains: CODE\(0x[A-Fa-f0-9]+\) b\)!,
320+
{ }, 'INC hooks do not segfault when overwritten');
321+
}
322+
{
323+
local $::TODO = "Pending error message improvement";
324+
# this is the defined behavior, but in older perls the error message
325+
# would lie and say "contains: a b", which is true in the sense that
326+
# it is the value of @INC after the require, but not the directory
327+
# list that was looked at.
328+
fresh_perl_like(
329+
'@INC = (sub { @INC=("a","b"); () }, "z"); '
330+
.'eval "require Frobnitz" or print $@',
331+
qr!\(\@INC contains: CODE\(0x[A-Fa-f0-9]+\) b\)!,
332+
{ }, 'INC hooks that overwrite @INC continue as expected (skips a and z)');
333+
}
334+
{
335+
local $::TODO = "Pending new feature \$INC";
336+
# as of 5.37.7
337+
fresh_perl_like(
338+
'@INC = (sub { @INC=qw(a b); undef $INC }, "z"); '
339+
.'eval "require Frobnitz" or print $@',
340+
qr!\(\@INC contains: CODE\(0x[A-Fa-f0-9]+\) a b\)!,
341+
{ }, 'INC hooks that overwrite @INC and undef $INC continue at start');
342+
}
343+
{
344+
local $::TODO = "Pending new feature: INCDIR";
345+
# as of 5.37.7
346+
fresh_perl_like(
347+
'sub CB::INCDIR { return "b", "c","d" }; '
348+
.'@INC = ("a",bless({},"CB"),"e");'
349+
.'eval "require Frobnitz" or print $@',
350+
qr!\(\@INC contains: a CB=HASH\(0x[A-Fa-f0-9]+\) b c d e\)!,
351+
{ }, 'INCDIR works as expected');
352+
}
353+
{
354+
local $::TODO = "Pending object handling improvements";
355+
# as of 5.37.7
356+
fresh_perl_like(
357+
'@INC = ("a",bless({},"CB"),"e");'
358+
.'eval "require Frobnitz" or print $@',
359+
qr!\(\@INC contains: a CB=HASH\(0x[A-Fa-f0-9]+\) e\)!,
360+
{ }, 'Objects with no INC or INCDIR method are stringified');
361+
}
362+
{
363+
local $::TODO = "Pending object handling improvements";
364+
# as of 5.37.7
365+
fresh_perl_like(
366+
'{package CB; use overload qw("")=>sub { "blorg"};} '
367+
.'@INC = ("a",bless({},"CB"),"e");'
368+
.'eval "require Frobnitz" or print $@',
369+
qr!\(\@INC contains: a blorg e\)!,
370+
{ }, 'Objects with overload and no INC or INCDIR method are stringified');
371+
}
372+
{
373+
local $::TODO = "Pending object handling improvments";
374+
# as of 5.37.7
375+
fresh_perl_like(
376+
'@INC = ("a",bless(sub { warn "blessed sub called" },"CB"),"e");'
377+
.'eval "require Frobnitz" or print $@',
378+
qr!blessed sub called.*\(\@INC contains: a CB=CODE\(0x[a-fA-F0-9]+\) e\)!s,
379+
{ }, 'Blessed subs with no hook methods are executed');
380+
}
381+
{
382+
local $::TODO = "Pending better error messages (eval)";
383+
# as of 5.37.7
384+
fresh_perl_like(
385+
'@INC = ("a",bless(sub { die "blessed sub called" },"CB"),"e");'
386+
.'eval "require Frobnitz" or print $@',
387+
qr!INC sub hook died--halting \@INC search!s,
388+
{ }, 'Blessed subs that die produce expected extra message');
389+
}
390+
{
391+
local $::TODO = "Pending better error messages (eval)";
392+
# as of 5.37.7
393+
fresh_perl_like(
394+
'sub CB::INC { die "bad mojo" } '
395+
.'@INC = ("a",bless(sub { die "blessed sub called" },"CB"),"e");'
396+
.'eval "require Frobnitz" or print $@',
397+
qr!bad mojo.*INC method hook died--halting \@INC search!s,
398+
{ }, 'Blessed subs with methods call method and produce expected message');
399+
}
400+
{
401+
local $::TODO = "Pending object handling improvments";
402+
# as of 5.37.7
403+
fresh_perl_like(
404+
'@INC = ("a",[bless([],"CB"),1],"e");'
405+
.'eval "require Frobnitz" or print $@',
406+
qr!Object with arguments in \@INC does not support a hook method!s,
407+
{ }, 'Blessed objects with no hook methods in array form produce expected exception');
408+
}
409+
{
410+
local $::TODO = "Pending new feature: INCDIR";
411+
# as of 5.37.7
412+
fresh_perl_like(
413+
'sub CB::INCDIR { "i" } sub CB2::INCDIR { }'
414+
.'@INC = ("a",bless(sub{"b"},"CB"),bless(sub{"c"},"CB2"),"e");'
415+
.'eval "require Frobnitz" or print $@',
416+
qr!\(\@INC contains: a CB=CODE\(0x[a-fA-F0-9]+\) i CB2=CODE\(0x[a-fA-F0-9]+\) e\)!s,
417+
{ }, 'Blessed subs with INCDIR methods call INCDIR');
418+
}
419+
{
420+
local $::TODO = "Pending new feature: INCDIR";
421+
# as of 5.37.7
422+
fresh_perl_like(
423+
'sub CB::INCDIR { return @{$_[2]} }'
424+
.'@INC = ("a",[bless([],"CB"),"b"],"c");'
425+
.'eval "require Frobnitz" or print $@',
426+
qr!\(\@INC contains: a ARRAY\(0x[a-fA-F0-9]+\) CB=ARRAY\(0x[a-fA-F0-9]+\) b c\)!s,
427+
{ }, 'INCDIR ref returns are stringified');
428+
}

0 commit comments

Comments
 (0)