WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 4 years ago

#36199 closed defect (bug) (duplicate)

Calling do_action within the same action causes next priority block to be skipped.

Reported by: dougwollison Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.6
Component: Plugins Keywords:
Focuses: Cc:

Description

The do-while loop that do_action() and apply_filters() use—rather than a foreach loop—to iterate over the the hooks for an action/filter seems to cause some issues that can result in the callbacks in the next priority block to be skipped altogether.

For example, a theme I was testing something with called get_posts() within the pre_get_posts action so it could get a list of posts to exclude from the main query. Since that function calls the same action, the current handling of do_action and apply_filters (and their ref_array version) causes the filter list to be reset in the middle of it being performed, causing the next priority block to be skipped.

The same issue occurs when a callback removes itself to prevent an infinite loop and fails to re-add itself when it's done (though this can be blamed on programmer error for having it remove itself before the should-proceed check).

The only way around the issue without messing with core code would be to add throwaway hooks as a buffer between the known offending hooks, which frankly is ridiculous.

I've attached two patches made to plugin.php on trunk; one copies the $wp_filter[$tag] to a new variable to be iterated over in the do-while loop, and the other replaces the do-while loop with a foreach loop. I feel the later is the better option but I can't be sure there wasn't good reason for using the do-while loop in the first place. Both also include some code cleanup; adding curly braces to the various blocks that aren't using them.

Attachments (2)

36199-copyarray.patch (5.2 KB) - added by dougwollison 4 years ago.
This patch uses the $hooks = $wp_filters[$tag] method, copying the array before manipulating it via iteration.
36199-foreach.patch (4.9 KB) - added by dougwollison 4 years ago.
This patch uses the foreach loop method, iterating over the array the standard way.

Download all attachments as: .zip

Change History (3)

@dougwollison
4 years ago

This patch uses the $hooks = $wp_filters[$tag] method, copying the array before manipulating it via iteration.

@dougwollison
4 years ago

This patch uses the foreach loop method, iterating over the array the standard way.

#1 @DrewAPicture
4 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #17817.

Note: See TracTickets for help on using tickets.