From 26c03ea5fb83e84d8a6cec3f88bce37712003640 Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Tue, 15 Oct 2013 19:18:10 +0000 Subject: [PATCH] Core Updates: Verify that all files we're about to copy are actually writable, when using the direct transport. Once we begin to copy core files, all bets are off. This allows us to fail early when we'll otherwise need to stop midway through due to permissions issues, which is a particularly bad problem when only some files have permissions issues. see #22704. Built from https://develop.svn.wordpress.org/trunk@25794 git-svn-id: http://core.svn.wordpress.org/trunk@25706 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/update-core.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/wp-admin/includes/update-core.php b/wp-admin/includes/update-core.php index 7eaf24e203..a4b5cd76f2 100644 --- a/wp-admin/includes/update-core.php +++ b/wp-admin/includes/update-core.php @@ -692,6 +692,7 @@ function update_core($from, $to) { // Don't copy wp-content, we'll deal with that below $skip = array( 'wp-content' ); + $check_is_writable = array(); // Check to see which files don't really need updating - only available for 3.7 and higher if ( function_exists( 'get_core_checksums' ) ) { @@ -702,10 +703,30 @@ function update_core($from, $to) { continue; if ( file_exists( ABSPATH . $file ) && md5_file( ABSPATH . $file ) === $checksum ) $skip[] = $file; + else + $check_is_writable[ $file ] = ABSPATH . $file; } } } + // If we're using the direct method, we can predict write failures that are due to permissions. + if ( $wp_filesystem->method === 'direct' ) { + $files_writable = array_filter( $check_is_writable, array( $wp_filesystem, 'is_writable' ) ); + if ( $files_writable !== $check_is_writable ) { + $files_not_writable = array_diff_key( $check_is_writable, $files_writable ); + foreach ( $files_not_writable as $relative_file_not_writable => $file_not_writable ) { + // If the writable check failed, chmod file to 0644 and try again, same as copy_dir(). + $wp_filesystem->chmod( $file_not_writable, FS_CHMOD_FILE ); + if ( $wp_filesystem->is_writable( $file_not_writable ) ) + unset( $files_not_writable[ $relative_file_not_writable ] ); + } + + // Store package-relative paths (the key) of non-writable files in the WP_Error object. + if ( $files_not_writable ) + return new WP_Error( 'files_not_writable', __( 'Could not copy file.' ), array_keys( $files_not_writable ) ); + } + } + apply_filters( 'update_feedback', __( 'Enabling Maintenance mode…' ) ); // Create maintenance file to signal that we are upgrading $maintenance_string = '';