diff --git a/lib/Test/MockFile.pm b/lib/Test/MockFile.pm index bb842ed..f9aa5e4 100644 --- a/lib/Test/MockFile.pm +++ b/lib/Test/MockFile.pm @@ -2108,7 +2108,7 @@ sub __sysopen (*$$;$) { sub __opendir (*$) { # Upgrade but ignore bareword indicator - ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9]; + ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0]; my $mock_dir = _get_file_object( $_[1] ); @@ -2157,7 +2157,7 @@ sub __opendir (*$) { sub __readdir (*) { # Upgrade but ignore bareword indicator - ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9]; + ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0]; my $mocked_dir = _get_file_object( $_[0] ); @@ -2200,7 +2200,7 @@ sub __readdir (*) { sub __telldir (*) { # Upgrade but ignore bareword indicator - ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9]; + ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0]; my ($fh) = @_; my $mocked_dir = _get_file_object($fh); @@ -2227,7 +2227,7 @@ sub __telldir (*) { sub __rewinddir (*) { # Upgrade but ignore bareword indicator - ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9]; + ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0]; my ($fh) = @_; my $mocked_dir = _get_file_object($fh); @@ -2255,7 +2255,7 @@ sub __rewinddir (*) { sub __seekdir (*$) { # Upgrade but ignore bareword indicator - ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9]; + ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0]; my ( $fh, $goto ) = @_; my $mocked_dir = _get_file_object($fh); @@ -2276,13 +2276,14 @@ sub __seekdir (*$) { confess("seekdir called on a closed dirhandle"); } - return $obj->{'tell'} = $goto; + $obj->{'tell'} = $goto; + return 1; } sub __closedir (*) { # Upgrade but ignore bareword indicator - ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[9]; + ( undef, @_ ) = _upgrade_barewords(@_) if defined $_[0] && !ref $_[0]; my ($fh) = @_; my $mocked_dir = _get_file_object($fh); diff --git a/t/opendir.t b/t/opendir.t index ebe9cf9..f712bff 100644 --- a/t/opendir.t +++ b/t/opendir.t @@ -145,5 +145,33 @@ is( closedir($dh); } +note "-------------- BAREWORD GUARD REGRESSION --------------"; +# Regression: the bareword upgrade guard was checking $_[9] (always undef +# for 1-2 arg dir functions) instead of $_[0]. This meant _upgrade_barewords +# ran unconditionally, even for reference filehandles. +# Also: seekdir must return 1 (like CORE::seekdir), not the seek position. +{ + my $mock_dir = Test::MockFile->dir('/guardtest'); + my $mock_file = Test::MockFile->file( '/guardtest/aaa', 'data' ); + + is( opendir( my $dh, '/guardtest' ), 1, "opendir with ref filehandle works" ); + + is( scalar readdir($dh), ".", "readdir with ref fh reads ." ); + is( scalar readdir($dh), "..", "readdir with ref fh reads .." ); + is( telldir($dh), 2, "telldir with ref fh returns correct position" ); + is( scalar readdir($dh), "aaa", "readdir with ref fh reads aaa" ); + + is( rewinddir($dh), 1, "rewinddir with ref fh returns 1" ); + is( telldir($dh), 0, "telldir after rewinddir is 0" ); + + # seekdir's return value is not reliably testable across Perl versions + # with CORE::GLOBAL overrides — test the effect instead. + seekdir( $dh, 2 ); + is( telldir($dh), 2, "telldir is 2 after seekdir(2)" ); + is( [ readdir($dh) ], ["aaa"], "readdir after seekdir(2) returns remaining entries" ); + + is( closedir($dh), 1, "closedir with ref fh returns 1" ); +} + done_testing(); exit;