Opened 3 weeks ago
Last modified 3 weeks ago
#64550 new defect (bug)
wp_update_plugins function (possibly wp_update_themes) breaks when the transient setting fails
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | major | Version: | 6.8.3 |
| Component: | General | Keywords: | |
| Focuses: | Cc: |
Description
Because the result of updating the update_plugins transient is never checked at the end of the function (set_site_transient()), if the setting fails (e.g. because a plugin such as GravityView decided to use fancy emojis in their changelog) then the site becomes stuck with old versions of plugins, never displaying any updates.
To reproduce, try to make $dpdb->strip_invalid_text() return a different data array (/wp-includes/class-wpdb.php::2827). I managed to get this with [GravityView](https://www.gravitykit.com/products/gravityview/changelog), which has some new UTF emojis in the description.
Change History (4)
#2
@
3 weeks ago
I caught this issue on an utf8 table, which is, I assume how WP used to create its tables in prior versions. However, this doesn't cancel the original bug report's validity, which claims that the handling of such errors is deficient (non-existent).
#3
@
3 weeks ago
Here's a simple plugin which demonstrates the issue.
<?php /* Plugin Name: Destroy All Plugin Updates Description: This plugin might completely prevent you from getting any plugin updates. DO NOT INSTALL THIS ON A PRODUCTION SERVER! Version: 0.1 Update URI: https://example.test/destroy-all-plugin-updates/update */ add_filter( 'update_plugins_example.test', static function ( $update, $plugin_data, $plugin_file, $locales ) { $update = [ 'slug' => 'destroy-all-plugin-updates', 'version' => '0.2', 'url' => 'https://example.test/destroy-all-plugin-updates/details', // This is U+1F680 ROCKET 'foobar' => "\xf0\x9f\x9a\x80", ]; return $update; }, 10, 4 );
To test the above plugin:
- You will need a
utf8database to test this - if your database isutf8mb4, you could simply change yourwp_options.option_valuecolumn for testing purposes (note that this may destroy some Unicode characters in your database - do not try this on a production site):
ALTER TABLE wp_options MODIFY COLUMN option_value LONGTEXT CHARSET utf8 NOT NULL;
- Install an old version of some plugin - for example, Classic Editor 1.6.6.
- Log in to the admin section and visit the "Plugins" page. You should see "There is a new version of Classic Editor available. View version 1.6.7 details or update now."
- Install the above "Destroy All Plugin Updates" plugin in
wp-content/plugins/destroy-all-plugin-updates/destroy-all-plugin-updates.php. Activate the plugin. - Delete the old
update_pluginstransient. You can do this with WP-CLI:
wp transient delete --network update_plugins
- Now visit the "Plugins" page again. You should see there is no update available for Classic Editor (or any other plugin).
- Deactivate the "Destroy All Plugin Updates" plugin. You should start getting updates again.
Are your MySQL tables (in particular the
wp_optionstable) using theutf8mb4charset? Or are they using some other charset (maybeutf8mb3or justutf8)?