[wp-trac] [WordPress Trac] #59246: update_option returns true, even when the value didn't change, potentially adding back old data

WordPress Trac noreply at wordpress.org
Wed Aug 30 07:44:20 UTC 2023


#59246: update_option returns true, even when the value didn't change, potentially
adding back old data
--------------------------------+-----------------------------
 Reporter:  malthert            |      Owner:  (none)
     Type:  defect (bug)        |     Status:  new
 Priority:  normal              |  Milestone:  Awaiting Review
Component:  Options, Meta APIs  |    Version:
 Severity:  normal              |   Keywords:
  Focuses:                      |
--------------------------------+-----------------------------
 `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 );
 ```

 Result:
 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

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/59246>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list