Make WordPress Core

Opened 17 years ago

Closed 17 years ago

Last modified 15 years ago

#4625 closed defect (bug) (fixed)

apply_filters is broken

Reported by: denis-de-bernardy's profile 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 17 years ago.

Download all attachments as: .zip

Change History (13)

#1 @Otto42
17 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.

17 years ago

#2 @Nazgul
17 years ago

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

Added a patch based on the suggestion by Otto42.

#3 @santosj
17 years ago

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

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

#4 @Otto42
17 years ago

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

#5 @darkdragon
17 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.

#6 @markjaquith
17 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.

#7 @darkdragon
17 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.

#8 @markjaquith
17 years ago

I like that reason. :-)

#9 @markjaquith
17 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

#10 @Denis-de-Bernardy
17 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

the same problem occurs for do_action

#11 @DD32
17 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

#12 @ryan
17 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.