Skip to content

Commit 1810bc5

Browse files
committed
File::stat: don't die on references
Only treat arguments as bareword filehandles if they're plain strings, not references. Otherwise Symbol::qualify() will just return $arg as-is, even if it is not a GLOB reference. Fixes #23507.
1 parent fca8f27 commit 1810bc5

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

lib/File/stat.pm

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package File::stat 1.14;
1+
package File::stat 1.15;
22
use v5.38;
33

44
use warnings::register;
@@ -200,14 +200,16 @@ sub stat :prototype($) {
200200
my $arg = shift;
201201
my $st = populate(CORE::stat $arg);
202202
return $st if defined $st;
203-
my $fh;
203+
return if ref $arg;
204+
# ... maybe $arg is the name of a bareword handle?
205+
my $fh;
204206
{
205-
local $!;
206-
no strict 'refs';
207-
require Symbol;
208-
$fh = \*{ Symbol::qualify( $arg, caller() )};
209-
return unless defined fileno $fh;
210-
}
207+
local $!;
208+
no strict 'refs';
209+
require Symbol;
210+
$fh = \*{ Symbol::qualify( $arg, caller() )};
211+
return unless defined fileno $fh;
212+
}
211213
return populate(CORE::stat $fh);
212214
}
213215

lib/File/stat.t

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,40 @@ SKIP:
191191
ok(-p($pstat), "check -p detects a pipe");
192192
}
193193

194+
{
195+
# GH #23507
196+
{
197+
package PathObj;
198+
use overload
199+
'""' => sub { $_[0]->to_string },
200+
fallback => 1;
201+
202+
sub new {
203+
my $class = shift;
204+
bless { path => $_[0] }, $class
205+
}
206+
207+
sub to_string {
208+
my $self = shift;
209+
$self->{path}
210+
}
211+
}
212+
213+
my $good_path = PathObj->new($file);
214+
my $bad_path = PathObj->new('/ no such file');
215+
216+
# explicit stringification
217+
isa_ok stat("$good_path"), 'File::stat', 'stat("$good_path")';
218+
is stat("$bad_path"), undef, 'stat("$bad_path") fails by returning undef';
219+
# implicit stringification
220+
isa_ok stat($good_path), 'File::stat', 'stat($good_path)';
221+
is stat($bad_path), undef, 'stat($bad_path) fails by returning undef';
222+
# and for good measure, unblessed references
223+
is stat(\42), undef, 'stat(\42) fails by returning undef';
224+
is stat([]), undef, 'stat([]) fails by returning undef';
225+
is stat({}), undef, 'stat({}) fails by returning undef';
226+
}
227+
194228
# Testing pretty much anything else is unportable.
195229

196230
done_testing;

0 commit comments

Comments
 (0)