WordPress.org

Make WordPress Core

Changeset 31206


Ignore:
Timestamp:
01/16/2015 04:45:21 PM (5 years ago)
Author:
boonebgorges
Message:

Bail out of hierarchy loops in _pad_term_counts().

Taxonomy hierarchy loops should not occur naturally, but when they do, the
logic of _pad_term_counts() could result in infinite loops, leading to
timeouts. We avoid this by breaking when a loop is detected.

Fixes #20635.

Location:
trunk
Files:
2 edited

Legend:

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

    r31168 r31206  
    39173917
    39183918    // Touch every ancestor's lookup row for each post in each term
     3919    $ancestors = array();
    39193920    foreach ( $term_ids as $term_id ) {
     3921        $ancestors[] = $term_id;
    39203922        $child = $term_id;
    39213923        while ( !empty( $terms_by_id[$child] ) && $parent = $terms_by_id[$child]->parent ) {
     3924            if ( in_array( $parent, $ancestors ) ) {
     3925                break;
     3926            }
     3927
    39223928            if ( !empty( $term_items[$term_id] ) )
    39233929                foreach ( $term_items[$term_id] as $item_id => $touches ) {
  • trunk/tests/phpunit/tests/term/getTerms.php

    r31024 r31206  
    10381038        $actual = wp_list_pluck( $terms, 'term_id' );
    10391039        $this->assertEqualSets( $expected, $actual );
     1040    }
     1041
     1042    /*
     1043     * @ticket 20635
     1044     */
     1045    public function test_pad_counts_should_not_recurse_infinitely_when_term_hierarchy_has_a_loop() {
     1046        remove_filter( 'wp_update_term_parent', 'wp_check_term_hierarchy_for_loops', 10 );
     1047
     1048        $c1 = $this->factory->category->create();
     1049        $c2 = $this->factory->category->create( array( 'parent' => $c1 ) );
     1050        $c3 = $this->factory->category->create( array( 'parent' => $c2 ) );
     1051        wp_update_term( $c1, 'category', array( 'parent' => $c3 ) );
     1052
     1053        add_filter( 'wp_update_term_parent', 'wp_check_term_hierarchy_for_loops', 10, 3 );
     1054
     1055        $posts = $this->factory->post->create_many( 3 );
     1056        wp_set_post_terms( $posts[0], $c1, 'category' );
     1057        wp_set_post_terms( $posts[1], $c2, 'category' );
     1058        wp_set_post_terms( $posts[2], $c3, 'category' );
     1059
     1060        $terms = get_terms( 'category', array(
     1061            'pad_counts' => true,
     1062        ) );
     1063
     1064        $this->assertEqualSets( array( $c1, $c2, $c3 ), wp_list_pluck( $terms, 'term_id' ) );
    10401065    }
    10411066
Note: See TracChangeset for help on using the changeset viewer.