This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix File::stat's -x and -X for root for directories and executable files.
authorNicholas Clark <nick@ccl4.org>
Mon, 18 Jun 2012 11:09:02 +0000 (13:09 +0200)
committerNicholas Clark <nick@ccl4.org>
Thu, 21 Jun 2012 07:00:36 +0000 (09:00 +0200)
Previously File::stat's overloaded -x and -X operators did not give
the correct results for directories or executable files when running as
root. They had been treating executable permissions for root just like for
any other user, performing group membership tests etc. for files not owned
by root. They now follow the correct Unix behaviour - for a directory they
are always true, and for a file if any of the three execute permission bits
are set then they report that root can execute the file. Perl's builtin
-x and -X operators, added in Perl 2, have always been correct.

lib/File/stat.pm
pod/perldelta.pod

index 90d53d7..b631fbf 100644 (file)
@@ -10,7 +10,7 @@ BEGIN { *warnif = \&warnings::warnif }
 
 our(@EXPORT, @EXPORT_OK, %EXPORT_TAGS);
 
-our $VERSION = '1.06';
+our $VERSION = '1.07';
 
 my @fields;
 BEGIN { 
@@ -87,15 +87,22 @@ else {
     *cando = sub {
         my ($s, $mode, $eff) = @_;
         my $uid = $eff ? $> : $<;
-
-        # If we're root on unix and we are not testing for executable
-        # status, then all file tests are true.
-        $^O ne "VMS" and $uid == 0 and !($mode & 0111) and return 1;
-
         my ($stmode, $stuid, $stgid) = @$s[2,4,5];
 
         # This code basically assumes that the rwx bits of the mode are
         # the 0777 bits, but so does Perl_cando.
+
+        if ($uid == 0 && $^O ne "VMS") {
+            # If we're root on unix
+            # not testing for executable status => all file tests are true
+            return 1 if !($mode & 0111);
+            # testing for executable status =>
+            # for a file, any x bit will do
+            # for a directory, always true
+            return 1 if $stmode & 0111 || S_ISDIR($stmode);
+            return "";
+        }
+
         if ($stuid == $uid) {
             $stmode & $mode         and return 1;
         }
index efc101b..03d4bfb 100644 (file)
@@ -97,7 +97,16 @@ XXX
 
 =item *
 
-L<XXX> has been upgraded from version 0.69 to version 0.70.
+L<File::stat> has been upgraded from version 1.06 to 1.07.
+
+Previously C<File::stat>'s overloaded C<-x> and C<-X> operators did not give
+the correct results for directories or executable files when running as
+root. They had been treating executable permissions for root just like for
+any other user, performing group membership tests I<etc> for files not owned
+by root. They now follow the correct Unix behaviour - for a directory they
+are always true, and for a file if any of the three execute permission bits
+are set then they report that root can execute the file. Perl's builtin
+C<-x> and C<-X> operators have always been correct.
 
 =back