Skip to content

Commit 8b764d6

Browse files
Koan-Botclaude
andcommitted
fix: correct bareword check typo $_[9] -> $_[0] in dir functions
The _upgrade_barewords guard in opendir/readdir/seekdir/rewinddir/telldir/ closedir was checking $_[9] (always undef for 1-2 arg functions) instead of $_[0]. This caused the upgrade path to run unconditionally, even for reference filehandles. Also adjust seekdir test to verify its effect (telldir position) rather than its return value, which is not reliably consistent across Perl versions when using CORE::GLOBAL overrides. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 599959b commit 8b764d6

2 files changed

Lines changed: 36 additions & 7 deletions

File tree

lib/Test/MockFile.pm

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,7 +2108,7 @@ sub __sysopen (*$$;$) {
21082108
sub __opendir (*$) {
21092109

21102110
# Upgrade but ignore bareword indicator
2111-
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9];
2111+
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0];
21122112

21132113
my $mock_dir = _get_file_object( $_[1] );
21142114

@@ -2157,7 +2157,7 @@ sub __opendir (*$) {
21572157
sub __readdir (*) {
21582158

21592159
# Upgrade but ignore bareword indicator
2160-
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9];
2160+
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0];
21612161

21622162
my $mocked_dir = _get_file_object( $_[0] );
21632163

@@ -2200,7 +2200,7 @@ sub __readdir (*) {
22002200
sub __telldir (*) {
22012201

22022202
# Upgrade but ignore bareword indicator
2203-
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9];
2203+
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0];
22042204

22052205
my ($fh) = @_;
22062206
my $mocked_dir = _get_file_object($fh);
@@ -2227,7 +2227,7 @@ sub __telldir (*) {
22272227
sub __rewinddir (*) {
22282228

22292229
# Upgrade but ignore bareword indicator
2230-
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9];
2230+
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0];
22312231

22322232
my ($fh) = @_;
22332233
my $mocked_dir = _get_file_object($fh);
@@ -2255,7 +2255,7 @@ sub __rewinddir (*) {
22552255
sub __seekdir (*$) {
22562256

22572257
# Upgrade but ignore bareword indicator
2258-
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9];
2258+
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0];
22592259

22602260
my ( $fh, $goto ) = @_;
22612261
my $mocked_dir = _get_file_object($fh);
@@ -2276,13 +2276,14 @@ sub __seekdir (*$) {
22762276
confess("seekdir called on a closed dirhandle");
22772277
}
22782278

2279-
return $obj->{'tell'} = $goto;
2279+
$obj->{'tell'} = $goto;
2280+
return 1;
22802281
}
22812282

22822283
sub __closedir (*) {
22832284

22842285
# Upgrade but ignore bareword indicator
2285-
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9];
2286+
( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0];
22862287

22872288
my ($fh) = @_;
22882289
my $mocked_dir = _get_file_object($fh);

t/opendir.t

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,5 +145,33 @@ is(
145145
closedir($dh);
146146
}
147147

148+
note "-------------- BAREWORD GUARD REGRESSION --------------";
149+
# Regression: the bareword upgrade guard was checking $_[9] (always undef
150+
# for 1-2 arg dir functions) instead of $_[0]. This meant _upgrade_barewords
151+
# ran unconditionally, even for reference filehandles.
152+
# Also: seekdir must return 1 (like CORE::seekdir), not the seek position.
153+
{
154+
my $mock_dir = Test::MockFile->dir('/guardtest');
155+
my $mock_file = Test::MockFile->file( '/guardtest/aaa', 'data' );
156+
157+
is( opendir( my $dh, '/guardtest' ), 1, "opendir with ref filehandle works" );
158+
159+
is( scalar readdir($dh), ".", "readdir with ref fh reads ." );
160+
is( scalar readdir($dh), "..", "readdir with ref fh reads .." );
161+
is( telldir($dh), 2, "telldir with ref fh returns correct position" );
162+
is( scalar readdir($dh), "aaa", "readdir with ref fh reads aaa" );
163+
164+
is( rewinddir($dh), 1, "rewinddir with ref fh returns 1" );
165+
is( telldir($dh), 0, "telldir after rewinddir is 0" );
166+
167+
# seekdir's return value is not reliably testable across Perl versions
168+
# with CORE::GLOBAL overrides — test the effect instead.
169+
seekdir( $dh, 2 );
170+
is( telldir($dh), 2, "telldir is 2 after seekdir(2)" );
171+
is( [ readdir($dh) ], ["aaa"], "readdir after seekdir(2) returns remaining entries" );
172+
173+
is( closedir($dh), 1, "closedir with ref fh returns 1" );
174+
}
175+
148176
done_testing();
149177
exit;

0 commit comments

Comments
 (0)