Make WordPress Core


Ignore:
Timestamp:
10/06/2023 04:31:22 PM (21 months ago)
Author:
flixos90
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/option.php

    r56788 r56796  
    860860
    861861    if ( ! wp_installing() ) {
    862         $alloptions = wp_load_alloptions( true );
    863         if ( isset( $alloptions[ $option ] ) ) {
     862        if ( ! isset( $update_args['autoload'] ) ) {
     863            // Update the cached value based on where it is currently cached.
     864            $alloptions = wp_load_alloptions( true );
     865            if ( isset( $alloptions[ $option ] ) ) {
     866                $alloptions[ $option ] = $serialized_value;
     867                wp_cache_set( 'alloptions', $alloptions, 'options' );
     868            } else {
     869                wp_cache_set( $option, $serialized_value, 'options' );
     870            }
     871        } elseif ( 'yes' === $update_args['autoload'] ) {
     872            // Delete the individual cache, then set in alloptions cache.
     873            wp_cache_delete( $option, 'options' );
     874
     875            $alloptions = wp_load_alloptions( true );
    864876            $alloptions[ $option ] = $serialized_value;
    865877            wp_cache_set( 'alloptions', $alloptions, 'options' );
    866878        } else {
     879            // Delete the alloptions cache, then set the individual cache.
     880            $alloptions = wp_load_alloptions( true );
     881            if ( isset( $alloptions[ $option ] ) ) {
     882                unset( $alloptions[ $option ] );
     883                wp_cache_set( 'alloptions', $alloptions, 'options' );
     884            }
     885
    867886            wp_cache_set( $option, $serialized_value, 'options' );
    868887        }
Note: See TracChangeset for help on using the changeset viewer.