mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
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:
parent
478cd02dfe
commit
cc64ed22bd
@ -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' );
|
||||
}
|
||||
}
|
||||
|
||||
@ -777,4 +777,36 @@ class Tests_Option_Option extends WP_UnitTestCase {
|
||||
// Assert that the filter is still present.
|
||||
$this->assertSame( 10, has_filter( 'pre_option_foo', '__return_zero' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that calling update_option() with changed autoload from 'no' to 'yes' updates the cache correctly.
|
||||
*
|
||||
* This ensures that no stale data is served in case the option is deleted after.
|
||||
*
|
||||
* @ticket 51352
|
||||
*
|
||||
* @covers ::update_option
|
||||
*/
|
||||
public function test_update_option_with_autoload_change_no_to_yes() {
|
||||
add_option( 'foo', 'value1', '', 'no' );
|
||||
update_option( 'foo', 'value2', 'yes' );
|
||||
delete_option( 'foo' );
|
||||
$this->assertFalse( get_option( 'foo' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that calling update_option() with changed autoload from 'yes' to 'no' updates the cache correctly.
|
||||
*
|
||||
* This ensures that no stale data is served in case the option is deleted after.
|
||||
*
|
||||
* @ticket 51352
|
||||
*
|
||||
* @covers ::update_option
|
||||
*/
|
||||
public function test_update_option_with_autoload_change_yes_to_no() {
|
||||
add_option( 'foo', 'value1', '', 'yes' );
|
||||
update_option( 'foo', 'value2', 'no' );
|
||||
delete_option( 'foo' );
|
||||
$this->assertFalse( get_option( 'foo' ) );
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user