From 204ca72a667720b2182f6a8fce48af3a799a9762 Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Tue, 15 Oct 2013 19:17:56 +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. git-svn-id: https://develop.svn.wordpress.org/trunk@25794 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/update-core.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/wp-admin/includes/update-core.php b/src/wp-admin/includes/update-core.php index 7eaf24e203..a4b5cd76f2 100644 --- a/src/wp-admin/includes/update-core.php +++ b/src/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 = '';