From 50a0efdda814efaaf0dfe7861fdc785429639a3b Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Thu, 25 Jun 2020 07:13:22 +0000 Subject: [PATCH] Upgrade/Install: Invalidate OPcache for PHP files during updates. When files are copied into place, check whether opcode invalidation is available and attempt to invalidate to avoid unintended behavior or fatal errors from themes, plugins, or core. Introduces `wp_opcache_invalidate()` to allow safe invalidation of PHP files from opcode cache, and a filter, `wp_opcache_invalidate_file` to override the behavior. Replaces the existing calls to `opcache_invalidate()` in the plugin and theme editors to use the new function. Thanks to jnylen0 for porting over a patch from ClassicPress that provided much of the approach for what is being committed. Props nigro.simone, dd32, JasWSInc, szepe.viktor, swissspidy, JanR, asalce, Garavani, pavelevap, pputzer, GregLone, benoitchantre, jadonn, doc987, kraftbj, Krstarica, jnylen0, nextendweb, williampatton, ayeshrajans, joostdevalk, stevenkussmaul, boogah, jorbin, mikeschroder. Fixes #36455, #50354. git-svn-id: https://develop.svn.wordpress.org/trunk@48160 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/class-core-upgrader.php | 1 + src/wp-admin/includes/file.php | 81 +++++++++++++++++-- src/wp-admin/includes/update-core.php | 13 ++- 3 files changed, 87 insertions(+), 8 deletions(-) diff --git a/src/wp-admin/includes/class-core-upgrader.php b/src/wp-admin/includes/class-core-upgrader.php index 7ef49f1f1c..d7305589bf 100644 --- a/src/wp-admin/includes/class-core-upgrader.php +++ b/src/wp-admin/includes/class-core-upgrader.php @@ -161,6 +161,7 @@ class Core_Upgrader extends WP_Upgrader { } $wp_filesystem->chmod( $wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE ); + wp_opcache_invalidate( ABSPATH . 'wp-admin/includes/update-core.php' ); require_once ABSPATH . 'wp-admin/includes/update-core.php'; if ( ! function_exists( 'update_core' ) ) { diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index 08215e5d2b..ec01eb799a 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -498,9 +498,7 @@ function wp_edit_theme_plugin_file( $args ) { if ( false === $written ) { return new WP_Error( 'unable_to_write', __( 'Unable to write to file.' ) ); } - if ( 'php' === $extension && function_exists( 'opcache_invalidate' ) ) { - opcache_invalidate( $real_file, true ); - } + wp_opcache_invalidate( $real_file, true ); if ( $is_active && 'php' === $extension ) { @@ -608,9 +606,7 @@ function wp_edit_theme_plugin_file( $args ) { // Roll-back file change. file_put_contents( $real_file, $previous_content ); - if ( function_exists( 'opcache_invalidate' ) ) { - opcache_invalidate( $real_file, true ); - } + wp_opcache_invalidate( $real_file, true ); if ( ! isset( $result['message'] ) ) { $message = __( 'Something went wrong.' ); @@ -1743,6 +1739,7 @@ function copy_dir( $from, $to, $skip_list = array() ) { return new WP_Error( 'copy_failed_copy_dir', __( 'Could not copy file.' ), $to . $filename ); } } + wp_opcache_invalidate( $to . $filename ); } elseif ( 'd' === $fileinfo['type'] ) { if ( ! $wp_filesystem->is_dir( $to . $filename ) ) { if ( ! $wp_filesystem->mkdir( $to . $filename, FS_CHMOD_DIR ) ) { @@ -2277,3 +2274,75 @@ function wp_print_request_filesystem_credentials_modal() { 3.2 upgrade, as well as for those - * upgrading to 3.7+. + * This is a standalone copy of the `copy_dir()` function that is used to + * upgrade the core files. It is placed here so that the version of this + * function from the *new* WordPress version will be called. + * + * It was initially added for the 3.1 -> 3.2 upgrade. * * @ignore * @since 3.2.0 * @since 3.7.0 Updated not to use a regular expression for the skip list. * * @see copy_dir() + * @link https://core.trac.wordpress.org/ticket/17173 * * @global WP_Filesystem_Base $wp_filesystem * @@ -1355,6 +1359,11 @@ function _copy_dir( $from, $to, $skip_list = array() ) { return new WP_Error( 'copy_failed__copy_dir', __( 'Could not copy file.' ), $to . $filename ); } } + + // `wp_opcache_invalidate()` only exists in WordPress 5.5, so don't run it when upgrading to 5.5. + if ( function_exists( 'wp_opcache_invalidate' ) ) { + wp_opcache_invalidate( $to . $filename ); + } } elseif ( 'd' === $fileinfo['type'] ) { if ( ! $wp_filesystem->is_dir( $to . $filename ) ) { if ( ! $wp_filesystem->mkdir( $to . $filename, FS_CHMOD_DIR ) ) {