WordPress.org

Make WordPress Core

Ticket #29544: 0001-3rd-patch.-Includes-some-more-bugfixes.patch

File 0001-3rd-patch.-Includes-some-more-bugfixes.patch, 17.3 KB (added by mnelson4, 7 years ago)

3rd patch

  • tests/phpunit/includes/mock-fs.php

    From 6f2086c7ab5144a3e221686f48162a411edc3319 Mon Sep 17 00:00:00 2001
    From: Michael Nelson <michael@eventespresso.com>
    Date: Tue, 9 Sep 2014 11:24:01 -0700
    Subject: [PATCH] 3rd patch. Includes some more bugfixes
    
    ---
     tests/phpunit/includes/mock-fs.php             | 316 ++++++++++++++++++++++++-
     tests/phpunit/tests/filesystem/permissions.php | 108 +++++++++
     2 files changed, 411 insertions(+), 13 deletions(-)
     create mode 100644 tests/phpunit/tests/filesystem/permissions.php
    
    diff --git a/tests/phpunit/includes/mock-fs.php b/tests/phpunit/includes/mock-fs.php
    index 8873b5c..7991013 100644
    a b  
    11<?php
     2define( 'WP_Filesystem_MockFS_default_perms' , '0777' );
     3define( 'WP_Filesystem_MockFS_default_owner' , 'wp-owner' );
     4define( 'WP_Filesystem_MockFS_default_group' , 'wp-group' );
    25class WP_Filesystem_MockFS extends WP_Filesystem_Base {
    36        private $cwd;
    47
    58        // Holds a array of objects which contain an array of objects, etc.
    6         private $fs = null;
     9        public $fs = null;
    710
    811        // Holds a array of /path/to/file.php and /path/to/dir/ map to an object in $fs above
    912        // a fast more efficient way of determining if a path exists, and access to that node
    1013        private $fs_map = array();
    1114
     15        private $_current_system_user_name;
     16        private $_system_users = array();
     17
    1218        public $verbose = false; // Enable to debug WP_Filesystem_Base::find_folder() / etc.
    1319        public $errors = array();
    1420        public $method = 'MockFS';
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    4551                $this->cache = array(); // Used by find_folder() and friends
    4652                $this->cwd = isset( $this->fs_map[ $home_dir ] ) ? $this->fs_map[ $home_dir ] : '/';
    4753                $this->setfs( $paths );
     54                $this->add_system_user( WP_Filesystem_MockFS_default_owner );
    4855        }
    4956
    5057        /**
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    7279
    7380        /**
    7481         * Locates a filesystem "node"
     82         * @return MockFS_Node
    7583         */
    7684        private function locate_node( $path ) {
    7785                return isset( $this->fs_map[ $path ] ) ? $this->fs_map[ $path ] : false;
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    8795
    8896        // Here starteth the WP_Filesystem functions.
    8997
    90         function mkdir( $path, /* Optional args are ignored */ $chmod = false, $chown = false, $chgrp = false ) {
     98        function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) {
    9199                $path = trailingslashit( $path );
    92 
     100                //if the directory already exists, leave it alone
     101                if( $this->is_dir( $path ) ){
     102                        return FALSE;
     103                }
    93104                $parent_node = $this->locate_parent_node( $path );
    94105                if ( ! $parent_node ) {
    95106                        $dirname = str_replace( '\\', '/', dirname( $path ) );
     107                        if( $dirname == '/' ){
     108                                return FALSE;
     109                        }
    96110                        $this->mkdir( $dirname );
    97111                        $parent_node = $this->locate_parent_node( $path );
    98112                        if ( ! $parent_node )
    99113                                return false;
    100114                }
    101115
    102                 $node = new MockFS_Directory_Node( $path );
     116                $node = new MockFS_Directory_Node( $path, $chmod, $chown, $chgrp );
    103117
    104118                $parent_node->children[ $node->name ] = $node;
    105119                $this->fs_map[ $path ] = $node;
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    109123
    110124        function put_contents( $path, $contents = '', $mode = null ) {
    111125                if ( ! $this->is_dir( dirname( $path ) ) )
    112                         $this->mkdir( dirname( $path ) );
    113 
    114                 $parent = $this->locate_parent_node( $path );
    115                 $new_file = new MockFS_File_Node( $path, $contents );
     126                        $this->mkdir( dirname( $path ), $mode );
     127
     128                //if the file already exists, just change its contents
     129                $node = $this->locate_node( $path );
     130                if( $node ){
     131                        if( ! $node instanceof MockFS_File_Node ){
     132                                return FALSE;
     133                        }else{
     134                                $node->contents = $contents;
     135                        }
     136                        //if they specified what permissions to set, set them
     137                        if( $mode != NULL ){
     138                                $node->perms = $mode;
     139                        }
     140                }else{
     141                        $parent = $this->locate_parent_node( $path );
     142                        if( ! $parent ){
     143                                return FALSE;
     144                        }
     145                        $new_file = new MockFS_File_Node( $path, $contents, $mode );
     146                        $parent->children[ $new_file->name ] = $new_file;
     147                        $this->fs_map[ $path ] = $new_file;
     148                }
    116149
    117                 $parent->children[ $new_file->name ] = $new_file;
    118                 $this->fs_map[ $path ] = $new_file;
     150                return TRUE;
    119151        }
    120152
    121153        function get_contents( $file ) {
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    191223                return $ret;
    192224        }
    193225
     226        /**
     227         * Changes the permissions
     228         * @param string $file path to file/folder
     229         * @param string $mode
     230         * @param boolean $recursive
     231         * @return boolean success
     232         */
     233        public function chmod( $file, $mode = false, $recursive = false ) {
     234                $node = $this->locate_node( $file );
     235                if( ! $node instanceof MockFS_Node ){
     236                        return FALSE;
     237                }
     238                $node->perms = $mode;
     239                if( $node instanceof MockFS_Directory_Node && $recursive ){
     240                        foreach( $node->children as $child_node ){
     241                                $this->chmod( $child_node->path, $mode, $recursive );
     242                        }
     243                }
     244                return TRUE;
     245        }
     246        /**
     247         * CHanges the owner
     248         * @param string $file
     249         * @param string $owner name of owner
     250         * @param type $recursive
     251         */
     252        public function chown( $file, $owner, $recursive = false ) {
     253                $node = $this->locate_node( $file );
     254                if( ! $node instanceof MockFS_Node || ! $this->is_writable( $file ) ){
     255                        return FALSE;
     256                }
     257                $node->owner = $owner;
     258                if( $node instanceof MockFS_Directory_Node && $recursive ){
     259                        foreach( $node->children as $child_node ){
     260                                $this->chown( $child_node->path, $owner, $recursive );
     261                        }
     262                }
     263                return TRUE;
     264        }
     265        /**
     266         * Sets the group name
     267         * @param string $file
     268         * @param string $group
     269         * @param boolean $recursive
     270         * @return boolean success
     271         */
     272        public function chgrp( $file, $group, $recursive = false ) {
     273                $node = $this->locate_node( $file );
     274                if( ! $node instanceof MockFS_Node || ! $this->is_writable( $file ) ){
     275                        return FALSE;
     276                }
     277                $node->group = $group;
     278                if( $node instanceof MockFS_Directory_Node && $recursive ){
     279                        foreach( $node->children as $child_node ){
     280                                $this->chgrp( $child_node->path, $group, $recursive );
     281                        }
     282                }
     283                return TRUE;
     284        }
     285
     286        /**
     287         *
     288         * @param type $file
     289         * @return string | false on error
     290         */
     291        function owner( $file ) {
     292                $node = $this->locate_node( $file );
     293                if( ! $node instanceof MockFS_Node || ! $this->is_writable( $file ) ){
     294                        return FALSE;
     295                }else{
     296                        return $node->owner();
     297                }
     298        }
     299
     300        /**
     301         *
     302         * @param type $file
     303         * @return string | false on error
     304         */
     305        function group( $file ) {
     306                $node = $this->locate_node( $file );
     307                if( ! $node instanceof MockFS_Node ){
     308                        return FALSE;
     309                }else{
     310                        return $node->group();
     311                }
     312        }
     313
     314        /**
     315         * Gets the permissions on the file
     316         * @return string | false on error
     317         */
     318        public function getchmod( $file ){
     319                $node = $this->locate_node( $file );
     320                if( ! $node instanceof MockFS_Node ){
     321                        return FALSE;
     322                }else{
     323                        return $node->perms();
     324                }
     325        }
     326
     327        /**
     328         * Users to swithch to
     329         * @param string $new_username
     330         * @return boolean success
     331         */
     332        public function change_current_system_user( $new_username ){
     333                if( isset( $this->_system_users[ $new_username ] ) ){
     334                        $this->_current_system_user_name = $new_username;
     335                }else{
     336                        return FALSE;
     337                }
     338        }
     339        /**
     340         * Gets the current mock FS system user, or FALSE if none has been set
     341         * @return MockFS_System_User
     342         */
     343        public function get_current_system_user(){
     344                if( isset( $this->_system_users[ $this->_current_system_user_name ] ) ){
     345                        return $this->_system_users[ $this->_current_system_user_name ];
     346                }else{
     347                        return FALSE;
     348                }
     349        }
     350
     351        /**
     352         * Adds the specified user. Returns that new user obejct or FALSE
     353         * @param string $username
     354         * @param string $groupname
     355         * @return boolean|\MockFS_System_User
     356         */
     357        function add_system_user( $username, $groupname = NULL ){
     358                if( isset( $this->_system_users[ $username ] ) ){
     359                        return FALSE;
     360                }
     361                if( ! $groupname ){
     362                        $groupname = WP_Filesystem_MockFS_default_group;
     363                }
     364                $user = new MockFS_System_User( $username, $groupname );
     365                $this->_current_system_user_name = $user->username;
     366                $this->_system_users[ $user->username ] = $user;
     367                return $user;
     368        }
     369
     370        function is_readable( $file ) {
     371                $user = $this->get_current_system_user();
     372                $file_node = $this->locate_node( $file );
     373                if( ! $file_node ){
     374                        return FALSE;
     375                }
     376                $perms =  intval( $file_node->perms(), 8 ) ;
     377                //owned by this user
     378                if( $file_node->owner() == $user->username ) {
     379                        if( $perms & 0400 ){
     380//                              echo "\r\n " . $user->username . " has permision to read " . $file_node->name . " because its perms are :" . $perms;
     381                                return TRUE;
     382                        }
     383                }
     384                //owned by this group?
     385                if( $file_node->group == $user->groupname ) {
     386                        if( $perms & 0040 ) {
     387//                              echo "\r\n " . $user->groupname . " has permision to read " . $file_node->name . " because its perms are :" . $perms;
     388                                return TRUE;
     389                        }
     390                }
     391                if( $perms & 0004){
     392//                      echo "\r\n anyone has permision to read " . $file_node->name . " because its perms are :" . $perms;
     393                        return TRUE;
     394                }else{
     395                        return FALSE;
     396                }
     397        }
     398        function is_writable( $file ) {
     399                $user = $this->get_current_system_user();
     400                $file_node = $this->locate_node( $file );
     401                if( ! $file_node ){
     402                        return FALSE;
     403                }
     404                $perms =  intval( $file_node->perms(), 8 ) ;
     405                //owned by this user
     406                if( $file_node->owner() == $user->username ) {
     407                        if( $perms & 0200 ){
     408//                              echo "\r\n " . $user->username . " has permision to read " . $file_node->name . " because its perms are :" . $perms;
     409                                return TRUE;
     410                        }
     411                }
     412                //owned by this group?
     413                if( $file_node->group == $user->groupname ) {
     414                        if( $perms & 0020 ) {
     415//                              echo "\r\n " . $user->groupname . " has permision to read " . $file_node->name . " because its perms are :" . $perms;
     416                                return TRUE;
     417                        }
     418                }
     419                if( $perms & 0002){
     420//                      echo "\r\n anyone has permision to read " . $file_node->name . " because its perms are :" . $perms;
     421                        return TRUE;
     422                }else{
     423                        return FALSE;
     424                }
     425        }
     426        /**
     427         *
     428         * @param type $path
     429         * @param type $time
     430         * @param type $atime
     431         * @return boolean
     432         */
     433        function touch( $path, $time = 0, $atime = 0 ) {
     434                if( ! $this->exists(  $path ) ){
     435                        $this->put_contents($path);
     436                        return TRUE;
     437                }else{
     438                        //if we kept track of when a file was last edited we would update it
     439                        return TRUE;
     440                }
     441        }
     442
     443
    194444}
    195445
    196446class MockFS_Node {
    197447        public $name; // The "name" of the entry, does not include a slash (exception, root)
    198448        public $type; // The type of the entry 'f' for file, 'd' for Directory
    199449        public $path; // The full path to the entry.
     450        public $perms; //permissions associated with this file or folder
     451        public $owner; //the owner name of the file or folder
     452        public $group; //the group of this file or folder
    200453
    201         function __construct( $path ) {
     454        function __construct( $path, $chmod = NULL, $chown = NULL, $chgrp = NULL ) {
    202455                $this->path = $path;
    203456                $this->name = basename( $path );
     457                if( ! $chmod ) {
     458                        $chmod = WP_Filesystem_MockFS_default_perms;
     459                }
     460                if( ! $chown ) {
     461                        $chown = WP_Filesystem_MockFS_default_owner;
     462                }
     463                if( ! $chgrp ) {
     464                        $chgrp = WP_Filesystem_MockFS_default_group;
     465                }
     466                $this->perms = $chmod;
     467                $this->owner = $chown;
     468                $this->group = $chgrp;
    204469        }
    205470
    206471        function is_file() {
    class MockFS_Node { 
    210475        function is_dir() {
    211476                return $this->type == 'd';
    212477        }
     478        /**
     479         *
     480         * @return string @see http://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation
     481         */
     482        function perms(){
     483                return $this->perms;
     484        }
     485        function owner(){
     486                return $this->owner;
     487        }
     488        function group(){
     489                return $this->group;
     490        }
    213491}
    214492
    215493class MockFS_Directory_Node extends MockFS_Node {
    class MockFS_File_Node extends MockFS_Node { 
    221499        public $type = 'f';
    222500        public $contents = ''; // The contents of the file
    223501
    224         function __construct( $path, $contents = '' ) {
    225                 parent::__construct( $path );
     502        function __construct( $path, $contents = '', $chmod = NULL, $chown = NULL, $chgrp = NULL ) {
     503                parent::__construct( $path, $chmod, $chown, $chgrp );
    226504                $this->contents = $contents;
    227505        }
     506}
     507
     508class MockFS_System_User{
     509        public $username;
     510        public $groupname;
     511        function __construct( $username, $groupname = NULL) {
     512                $this->username = $username;
     513                if( ! $groupname ){
     514                        $groupname = WP_Filesystem_MockFS_default_group;
     515                }
     516                $this->groupname = $groupname;
     517        }
    228518}
     519 No newline at end of file
  • new file tests/phpunit/tests/filesystem/permissions.php

    diff --git a/tests/phpunit/tests/filesystem/permissions.php b/tests/phpunit/tests/filesystem/permissions.php
    new file mode 100644
    index 0000000..bb12347
    - +  
     1<?php
     2/**
     3 *
     4 * permissions
     5 *
     6 * @package                     Event Espresso
     7 * @subpackage
     8 * @author                              Mike Nelson
     9 * @group filesystem
     10 */
     11class WP_Filesystem_permissions_UnitTestCases extends WP_Filesystem_UnitTestCase{
     12
     13        function test_mkdir(){
     14                global $wp_filesystem;
     15                $wp_filesystem->init('/');
     16                $folder_path = '/test/';
     17                $wp_filesystem->mkdir( $folder_path );
     18                $this->assertTrue( $wp_filesystem->exists( $folder_path ) );
     19                $this->assertEquals( WP_Filesystem_MockFS_default_perms, $wp_filesystem->getchmod( $folder_path ) );
     20                $this->assertEquals( WP_Filesystem_MockFS_default_owner, $wp_filesystem->owner( $folder_path ) );
     21                $this->assertEquals( WP_Filesystem_MockFS_default_group, $wp_filesystem->group( $folder_path ) );
     22        }
     23
     24        function test_chmod(){
     25                global $wp_filesystem;
     26                $wp_filesystem->init('/');
     27                $folder_path = '/test/';
     28                $wp_filesystem->mkdir( $folder_path );
     29                $this->assertEquals( WP_Filesystem_MockFS_default_perms, $wp_filesystem->getchmod( $folder_path ) );
     30                $wp_filesystem->chmod( $folder_path, 664 );
     31                $this->assertEquals( 664, $wp_filesystem->getchmod( $folder_path ) );
     32        }
     33
     34        function test_chown(){
     35                global $wp_filesystem;
     36                $wp_filesystem->init('/');
     37                $folder_path = '/test/';
     38                $wp_filesystem->mkdir( $folder_path );
     39                $this->assertEquals( WP_Filesystem_MockFS_default_owner, $wp_filesystem->owner( $folder_path ) );
     40                $wp_filesystem->chown( $folder_path, 'stranger');
     41                $this->assertEquals( 'stranger', $wp_filesystem->owner( $folder_path ) );
     42        }
     43
     44        function test_chgroup(){
     45                global $wp_filesystem;
     46                $wp_filesystem->init('/');
     47                $folder_path = '/test/';
     48                $wp_filesystem->mkdir( $folder_path );
     49                $this->assertEquals( WP_Filesystem_MockFS_default_group, $wp_filesystem->group( $folder_path ) );
     50                $success = $wp_filesystem->chgrp( $folder_path, 'globe-trotters');
     51                $this->assertEquals( 'globe-trotters', $wp_filesystem->group( $folder_path ) );
     52        }
     53
     54        function test_is_readable(){
     55                global $wp_filesystem;
     56                $wp_filesystem->init('/');
     57                $folder_path = '/test/';
     58                $wp_filesystem->mkdir( $folder_path );
     59                $this->assertEquals( WP_Filesystem_MockFS_default_perms, $wp_filesystem->getchmod( $folder_path ));
     60                $this->assertTrue( $wp_filesystem->is_readable( $folder_path ) );
     61                //switch to another user, although they should be able to read it too
     62                $other_user_same_group =  $wp_filesystem->add_system_user( 'other_user_same_group', WP_Filesystem_MockFS_default_group );
     63                $other_user_other_group = $wp_filesystem->add_system_user( 'other_user_other_group', 'other_group' );
     64                $wp_filesystem->change_current_system_user( $other_user_other_group->username );
     65                $this->assertTrue( $wp_filesystem->is_readable( $folder_path ) );
     66
     67                $wp_filesystem->change_current_system_user( WP_Filesystem_MockFS_default_owner );
     68                //change the permissions soo only someone in the same group can read
     69                $wp_filesystem->chmod( $folder_path, '770' );
     70                $this->assertEquals( '770', $wp_filesystem->getchmod( $folder_path ) );
     71                $this->assertTrue( $wp_filesystem->is_readable( $folder_path ) );
     72                //and now check the user in the same group can still read...
     73                $wp_filesystem->change_current_system_user( $other_user_same_group->username );
     74                $this->assertTrue( $wp_filesystem->is_readable( $folder_path ) );
     75                //..bu tthe user in a differeng group can't
     76                $wp_filesystem->change_current_system_user( $other_user_other_group->username );
     77                $this->assertFalse( $wp_filesystem->is_readable( $folder_path ) );
     78        }
     79
     80        function test_is_writable(){
     81                global $wp_filesystem;
     82                $wp_filesystem->init('/');
     83                $folder_path = '/test/';
     84                $wp_filesystem->mkdir( $folder_path );
     85                $this->assertEquals( WP_Filesystem_MockFS_default_perms, $wp_filesystem->getchmod( $folder_path ));
     86                $this->assertTrue( $wp_filesystem->is_writable( $folder_path ) );
     87                //switch to another user, although they should be able to write it too
     88                $other_user_same_group =  $wp_filesystem->add_system_user( 'other_user_same_group', WP_Filesystem_MockFS_default_group );
     89                $other_user_other_group = $wp_filesystem->add_system_user( 'other_user_other_group', 'other_group' );
     90                $wp_filesystem->change_current_system_user( $other_user_other_group->username );
     91                $this->assertTrue( $wp_filesystem->is_writable( $folder_path ) );
     92
     93                $wp_filesystem->change_current_system_user( WP_Filesystem_MockFS_default_owner );
     94                //change the permissions soo only someone in the same group can read
     95                $wp_filesystem->chmod( $folder_path, '770' );
     96                $this->assertEquals( '770', $wp_filesystem->getchmod( $folder_path ) );
     97                $this->assertTrue( $wp_filesystem->is_writable( $folder_path ) );
     98                //and now check the user in the same group can still write...
     99                $wp_filesystem->change_current_system_user( $other_user_same_group->username );
     100                $this->assertTrue( $wp_filesystem->is_writable( $folder_path ) );
     101                //..bu tthe user in a differeng group can't
     102                $wp_filesystem->change_current_system_user( $other_user_other_group->username );
     103                $this->assertFalse( $wp_filesystem->is_writable( $folder_path ) );
     104        }
     105
     106}
     107
     108// End of file permissions.php
     109 No newline at end of file