#4625 closed defect (bug) (fixed)
apply_filters is broken
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | 2.3 | Priority: | high |
Severity: | normal | Version: | 2.2.1 |
Component: | General | Keywords: | has-patch |
Focuses: | Cc: |
Description
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)
Change History (13)
#2
@
18 years ago
- Keywords has-patch added
- Priority changed from highest omg bbq to high
Added a patch based on the suggestion by Otto42.
#3
@
18 years ago
Shouldn't you also add it to the other? There are two in that file.
do { } while ( next($wp_filters[$tag]) );
#4
@
18 years ago
The other one is in do_action, and yeah, in theory it could be susceptible to the same issue.
#5
@
18 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
@
18 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
@
18 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.
#10
@
17 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
the same problem occurs for do_action
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.