Bail out of hierarchy loops in _get_term_children().

This prevents infinite loops that lead to PHP nesting limit fatal errors.

Props boonebgorges, sgrant.
Fixes #24461.
Built from https://develop.svn.wordpress.org/trunk@31207


git-svn-id: http://core.svn.wordpress.org/trunk@31188 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Boone Gorges 2015-01-16 17:10:22 +00:00
parent 991bfdebc1
commit 35f3f7bf63
2 changed files with 22 additions and 6 deletions

View File

@ -3825,11 +3825,15 @@ function _get_term_hierarchy($taxonomy) {
* @since 2.3.0
*
* @param int $term_id The ancestor term: all returned terms should be descendants of $term_id.
* @param array $terms The set of terms---either an array of term objects or term IDs---from which those that are descendants of $term_id will be chosen.
* @param string $taxonomy The taxonomy which determines the hierarchy of the terms.
* @param array $terms The set of terms - either an array of term objects or term IDs - from which those that
* are descendants of $term_id will be chosen.
* @param string $taxonomy The taxonomy which determines the hierarchy of the terms.
* @param array $ancestors Term ancestors that have already been identified. Passed by reference, to keep track of
* found terms when recursing the hierarchy. The array of located ancestors is used to prevent
* infinite recursion loops.
* @return array The subset of $terms that are descendants of $term_id.
*/
function _get_term_children($term_id, $terms, $taxonomy) {
function _get_term_children( $term_id, $terms, $taxonomy, &$ancestors = array() ) {
$empty_array = array();
if ( empty($terms) )
return $empty_array;
@ -3840,6 +3844,11 @@ function _get_term_children($term_id, $terms, $taxonomy) {
if ( ( 0 != $term_id ) && ! isset($has_children[$term_id]) )
return $empty_array;
// Include the term itself in the ancestors array, so we can properly detect when a loop has occurred.
if ( empty( $ancestors ) ) {
$ancestors[] = $term_id;
}
foreach ( (array) $terms as $term ) {
$use_id = false;
if ( !is_object($term) ) {
@ -3849,7 +3858,8 @@ function _get_term_children($term_id, $terms, $taxonomy) {
$use_id = true;
}
if ( $term->term_id == $term_id ) {
// Don't recurse if we've already identified the term as a child - this indicates a loop.
if ( in_array( $term->term_id, $ancestors ) ) {
continue;
}
@ -3862,7 +3872,13 @@ function _get_term_children($term_id, $terms, $taxonomy) {
if ( !isset($has_children[$term->term_id]) )
continue;
if ( $children = _get_term_children($term->term_id, $terms, $taxonomy) )
if ( $use_id ) {
$ancestors = array_merge( $ancestors, $term_list );
} else {
$ancestors = array_merge( $ancestors, wp_list_pluck( $term_list, 'term_id' ) );
}
if ( $children = _get_term_children( $term->term_id, $terms, $taxonomy, $ancestors) )
$term_list = array_merge($term_list, $children);
}
}

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.2-alpha-31206';
$wp_version = '4.2-alpha-31207';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.