[wp-trac] [WordPress Trac] #37679: Actions that remove and add themselves again, break other actions

WordPress Trac noreply at wordpress.org
Tue Aug 16 19:08:07 UTC 2016


#37679: Actions that remove and add themselves again, break other actions
-------------------------+-------------------------------------------------
 Reporter:  noplanman    |      Owner:
     Type:  defect       |     Status:  new
  (bug)                  |  Milestone:  Awaiting Review
 Priority:  normal       |    Version:  trunk
Component:  General      |   Keywords:  do_action, add_action,
 Severity:  major        |  remove_action, loop
  Focuses:               |
-------------------------+-------------------------------------------------
 Scenario:
 I have 2 actions for save_post with priorities 11 and 12, let's call them
 sp11 and sp12.

 sp11 gets called before sp12, which is correct.

 Now, if sp11 removes itself via `remove_action` and then adds itself again
 via `add_action`, sp12 is never called, BUT instead, sp11 is called again,
 so twice in total!

 I've dug into the code a bit and found the problem:
 This happens because the `$wp_filters['save_post']` array gets reordered
 and the call list isn't correct any more.

 The problem happens in the last loop of do_action
 [https://core.trac.wordpress.org/browser/tags/4.5.3/src/wp-
 includes/plugin.php#L523 here].

 Because the loop is using pointers, when an item is removed and re-added,
 the pointer is wrong if the items have changed their original position.

 For my example above, when sp11 gets removed and added again, it gets
 added to the end of the array, thus skipping over sp12 and calling sp11
 again.


 To help visualise what happens (simplified):

 {{{
 // Loop starts, current (first) element.
 $wp_filters['save_post'] => [
   11 => 'sp11', //pointer here
   12 => 'sp12',
 ];
 }}}
 -> execute sp11

 {{{
 // After remove_action and add_action in sp11.
 $wp_filters['save_post'] => [
   12 => 'sp12', //pointer here
   11 => 'sp11',
 ];
 }}}

 {{{
 // Next element.
 $wp_filters['save_post'] => [
   12 => 'sp12',
   11 => 'sp11', //pointer here
 ];
 }}}
 -> execute sp11

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


More information about the wp-trac mailing list