Make WordPress Core


Ignore:
Timestamp:
01/16/2015 05:09:11 PM (11 years ago)
Author:
boonebgorges
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/taxonomy.php

    r31206 r31207  
    38263826 *
    38273827 * @param int $term_id The ancestor term: all returned terms should be descendants of $term_id.
    3828  * @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.
    3829  * @param string $taxonomy The taxonomy which determines the hierarchy of the terms.
     3828 * @param array  $terms     The set of terms - either an array of term objects or term IDs - from which those that
     3829 *                          are descendants of $term_id will be chosen.
     3830 * @param string $taxonomy  The taxonomy which determines the hierarchy of the terms.
     3831 * @param array  $ancestors Term ancestors that have already been identified. Passed by reference, to keep track of
     3832 *                          found terms when recursing the hierarchy. The array of located ancestors is used to prevent
     3833 *                          infinite recursion loops.
    38303834 * @return array The subset of $terms that are descendants of $term_id.
    38313835 */
    3832 function _get_term_children($term_id, $terms, $taxonomy) {
     3836function _get_term_children( $term_id, $terms, $taxonomy, &$ancestors = array() ) {
    38333837    $empty_array = array();
    38343838    if ( empty($terms) )
     
    38403844    if  ( ( 0 != $term_id ) && ! isset($has_children[$term_id]) )
    38413845        return $empty_array;
     3846
     3847    // Include the term itself in the ancestors array, so we can properly detect when a loop has occurred.
     3848    if ( empty( $ancestors ) ) {
     3849        $ancestors[] = $term_id;
     3850    }
    38423851
    38433852    foreach ( (array) $terms as $term ) {
     
    38503859        }
    38513860
    3852         if ( $term->term_id == $term_id ) {
     3861        // Don't recurse if we've already identified the term as a child - this indicates a loop.
     3862        if ( in_array( $term->term_id, $ancestors ) ) {
    38533863            continue;
    38543864        }
     
    38633873                continue;
    38643874
    3865             if ( $children = _get_term_children($term->term_id, $terms, $taxonomy) )
     3875            if ( $use_id ) {
     3876                $ancestors = array_merge( $ancestors, $term_list );
     3877            } else {
     3878                $ancestors = array_merge( $ancestors, wp_list_pluck( $term_list, 'term_id' ) );
     3879            }
     3880
     3881            if ( $children = _get_term_children( $term->term_id, $terms, $taxonomy, $ancestors) )
    38663882                $term_list = array_merge($term_list, $children);
    38673883        }
Note: See TracChangeset for help on using the changeset viewer.