Make WordPress Core

Opened 3 months ago

#59246 new defect (bug)

update_option returns true, even when the value didn't change, potentially adding back old data

Reported by: malthert's profile malthert Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Options, Meta APIs Keywords:
Focuses: Cc:


update_option will inconsistently return true/false, depending on whether another update option call is made in the meantime.

While this isn't a problem per se, it creates inconsistent and unexpected behavior.

$a = get_option( 'a' );
$b = get_option( 'b' );

sleep( 5 ); placeholder for code that takes some time
$b = '2';
update_option( 'b', $b );
update_option( 'a', $a );
$a didn't change, so it shouldn't update but return false - but it will update and return true

Request 2:

$a = get_option( 'a' );
$b = get_option( 'b' );

$a = '7';
$b = '3';
update_option( 'b', $b );
update_option( 'a', $a );

Option 'a' will have a value of 1 instead of 7.

Why does this happen?
update_option uses get_option to get the $old_value - however the $old_value might in fact be a NEW value that was added in the meantime by another request.

This leads to unexpected behavior of update_option if called with unmodified data - since update_option sometimes behaves seemingly atomically, while in reality it doesn't - but most devs are not aware of this.

These are extremely hard to track down bugs for most developers.

Possible solution(s):

  • ignore this issue, and improve documentation to make it clear that update_option might update an option even if the value didn't change - if the option was modified in the meantime
  • add an additional parameter to update_option for $old_value to have people pass it in for comparison

Change History (0)

Note: See TracTickets for help on using tickets.