From cfbd76d97ce44fdca24fd170d9fb39afcf2bb2f9 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 6 Oct 2023 16:33:25 +0000 Subject: [PATCH] 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. Built from https://develop.svn.wordpress.org/trunk@56796 git-svn-id: http://core.svn.wordpress.org/trunk@56308 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/option.php | 23 +++++++++++++++++++++-- wp-includes/version.php | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/wp-includes/option.php b/wp-includes/option.php index 58c4113ffc..d2ffa675b1 100644 --- a/wp-includes/option.php +++ b/wp-includes/option.php @@ -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' ); } } diff --git a/wp-includes/version.php b/wp-includes/version.php index 89d44665d1..27adccf91e 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.4-beta2-56793'; +$wp_version = '6.4-beta2-56796'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.