Make WordPress Core

Opened 7 years ago

Closed 7 years ago

Last modified 5 years ago

#4625 closed defect (bug) (fixed)

apply_filters is broken

Reported by: Denis-de-Bernardy Owned by:
Milestone: 2.3 Priority: high
Severity: normal Version: 2.2.1
Component: General Keywords: has-patch
Focuses: Cc:


should be:

	foreach ( $wp_filter[$tag] as $filter ) {
		foreach( (array) $filter as $the_ )
			if ( !is_null($the_['function']) ){
				$args[1] = $string;
				$string = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));

because if you use remove_filter() at some point, you can end up with an empty array on $wp_filters[$tag]. using while ( next($wp_filters[$tag]) ) at that point ends up ignoring a whole batch of applicable filters.

Attachments (1)

4625.diff (432 bytes) - added by Nazgul 7 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 Otto427 years ago

A simpler change to fix this would be to change the while ( next($wp_filters[$tag]) ) into:
while ( next($wp_filters[$tag]) !== FALSE)

next() returns the next entry in $wp_filters[$tag], or false when there's no more there. While it's true that the empty array could fail the boolean evaluation, it cannot fail a !== FALSE check.

Nazgul7 years ago

comment:2 Nazgul7 years ago

  • Keywords has-patch added
  • Priority changed from highest omg bbq to high

Added a patch based on the suggestion by Otto42.

comment:3 santosj7 years ago

Shouldn't you also add it to the other? There are two in that file.

do { } while ( next($wp_filters[$tag]) );

comment:4 Otto427 years ago

The other one is in do_action, and yeah, in theory it could be susceptible to the same issue.

comment:5 darkdragon7 years ago

Holy cow! I was able to reproduce this and wow, that is messed up.

The patch works also. I'm going to test to see if the other one needs it also.

comment:6 markjaquith7 years ago

  • Milestone changed from 2.2.2 to 2.3 (trunk)

Is there any good reason to leave these as do...while loops? (other than making this fix a smaller patch, that is)

do...while loops have their place, but iterating through an array is not it.

comment:7 darkdragon7 years ago

Well, it could be faster having it as a while loop, but really, if all you need is to continue and iterate over all items, foreach might also work.

It is all the same. I think the do ... while was for making sure that the first item was iterated over. It is also perhaps safer to remove items while inside the array (perhaps, but would need testing for foreach).

while( ( $filter = next( $wp_filter[$tag] ) !== false)
    foreach( ... )


A good reason: Because it works and won't require more testing.

comment:8 markjaquith7 years ago

I like that reason. :-)

comment:9 markjaquith7 years ago

  • Resolution set to fixed
  • Status changed from new to closed

(In [5857]) explicitly check next() against FALSE when iterating through filters. Props Denis-de-Bernardy, Otto42, Nazgul, santosj (go team effort!). fixes #4625 for trunk

comment:10 Denis-de-Bernardy7 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

the same problem occurs for do_action

comment:11 DD327 years ago

the same problem occurs for do_action

The patch here only applied to apply_filters, but the SVN commit applied the patch to apply_filters and do_action.

Allthough i notice it wasnt applied to do_action_ref_array

comment:12 ryan7 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [5958]) explicitly check next() against FALSE in do_action_ref_array(). Props Denis-de-Bernardy, Otto42, Nazgul, santosj, DD32. fixes #4625 for trunk

Note: See TracTickets for help on using tickets.