Options, Meta APIs: Fix bug with update_option() updating the wrong cache, leading to potentially stale values being returned.

When using the `$autoload` parameter of `update_option()` alongside an option value update, prior to this changeset the function would update the incorrect cache, not respecting the new autoload value. This could have severe implications such as returning a stale option value when the option in fact had already been deleted.

This changeset fixes the bug alongside test coverage that failed with `trunk` but now passes.

Props kkmuffme, pentatonicfunk, SergeyBiryukov, oglekler, azaozz, spacedmonkey, nicolefurlan, joemcgill, flixos90.
Fixes #51352.


git-svn-id: https://develop.svn.wordpress.org/trunk@56796 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Felix Arntz
2023-10-06 16:31:22 +00:00
parent 478cd02dfe
commit cc64ed22bd
2 changed files with 53 additions and 2 deletions

View File

@@ -859,11 +859,30 @@ function update_option( $option, $value, $autoload = null ) {
}
if ( ! wp_installing() ) {
$alloptions = wp_load_alloptions( true );
if ( isset( $alloptions[ $option ] ) ) {
if ( ! isset( $update_args['autoload'] ) ) {
// Update the cached value based on where it is currently cached.
$alloptions = wp_load_alloptions( true );
if ( isset( $alloptions[ $option ] ) ) {
$alloptions[ $option ] = $serialized_value;
wp_cache_set( 'alloptions', $alloptions, 'options' );
} else {
wp_cache_set( $option, $serialized_value, 'options' );
}
} elseif ( 'yes' === $update_args['autoload'] ) {
// Delete the individual cache, then set in alloptions cache.
wp_cache_delete( $option, 'options' );
$alloptions = wp_load_alloptions( true );
$alloptions[ $option ] = $serialized_value;
wp_cache_set( 'alloptions', $alloptions, 'options' );
} else {
// Delete the alloptions cache, then set the individual cache.
$alloptions = wp_load_alloptions( true );
if ( isset( $alloptions[ $option ] ) ) {
unset( $alloptions[ $option ] );
wp_cache_set( 'alloptions', $alloptions, 'options' );
}
wp_cache_set( $option, $serialized_value, 'options' );
}
}