Make WordPress Core

Ticket #60855: 60855-FOR-ILLUSTRATION-PURPOSES-ONLY-DO-NOT-MERGE.patch

File 60855-FOR-ILLUSTRATION-PURPOSES-ONLY-DO-NOT-MERGE.patch, 2.5 KB (added by siliconforks, 23 months ago)

An example of implementing wp_mkdir_p() without using PHP's (buggy) recursive mkdir(). Note: this patch is simplified for illustration purposes and contains some issues - do not attempt to actually merge this.

  • src/wp-includes/functions.php

    diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php
    index 2b2e3379c7..9d0bbe3fd4 100644
    a b function wp_mkdir_p( $target ) { 
    20812081                $dir_perms = 0777;
    20822082        }
    20832083
    2084         if ( @mkdir( $target, $dir_perms, true ) ) {
     2084        /*
     2085         * FOR ILLUSTRATION PURPOSES ONLY - DO NOT MERGE THIS PATCH
     2086         */
    20852087
    2086                 /*
    2087                  * If a umask is set that modifies $dir_perms, we'll have to re-set
    2088                  * the $dir_perms correctly with chmod()
    2089                  */
    2090                 if ( ( $dir_perms & ~umask() ) !== $dir_perms ) {
    2091                         $folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
    2092                         for ( $i = 1, $c = count( $folder_parts ); $i <= $c; $i++ ) {
    2093                                 chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
     2088        /*
     2089         * If a umask is set that modifies $dir_perms, we'll have to re-set
     2090         * the $dir_perms correctly with chmod()
     2091         */
     2092        if ( ( $dir_perms & ~umask() ) !== $dir_perms ) {
     2093                $is_chmod_required = true;
     2094        } else {
     2095                $is_chmod_required = false;
     2096        }
     2097
     2098        /*
     2099         * We cannot use mkdir()'s own built-in recursive functionality
     2100         * (when the third argument is true) because it returns an error
     2101         * if the directory already exists.
     2102         * See https://core.trac.wordpress.org/ticket/60855.
     2103         */
     2104
     2105        $folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
     2106        for ( $i = 1, $c = count( $folder_parts ); $i <= $c; $i++ ) {
     2107                $intermediate_dir = $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) );
     2108                if ( @mkdir( $intermediate_dir ) ) {
     2109                        /*
     2110                         * The mkdir() call succeeded - set permissions if necessary and continue.
     2111                         */
     2112                        if ( $is_chmod_required ) {
     2113                                chmod( $intermediate_dir, $dir_perms );
     2114                        }
     2115                        continue;
     2116                } else {
     2117                        /*
     2118                         * The mkdir() call failed - try to find out why.
     2119                         */
     2120                        if ( file_exists( $intermediate_dir ) ) {
     2121                                /*
     2122                                 * It seems that $intermediate_dir already exists.
     2123                                 * If it's a directory, we can simply proceed to the next iteration.
     2124                                 * If it's not a directory, then return failure.
     2125                                 */
     2126                                if ( is_dir( $intermediate_dir ) ) {
     2127                                        continue;
     2128                                } else {
     2129                                        return false;
     2130                                }
     2131                        } else {
     2132                                /*
     2133                                 * It seems that $intermediate_dir does not exist.
     2134                                 * Return failure.
     2135                                 */
     2136                                return false;
    20942137                        }
    20952138                }
    2096 
    2097                 return true;
    20982139        }
    20992140
    2100         return false;
     2141        /*
     2142         * If we get here, mkdir() was able to create all intermediate directories.
     2143         * Return success.
     2144         */
     2145        return true;
    21012146}
    21022147
    21032148/**