WordPress.org

Make WordPress Core

Changeset 34492


Ignore:
Timestamp:
09/24/2015 02:03:05 PM (4 years ago)
Author:
wonderboymusic
Message:

Canonical/Rewrite: sanity check posts that are paged with <!--nextpage-->. Page numbers past the max number of pages are returning the last page of content and causing infinite duplicate content.

Awesome rewrite bug: the page query var was being set to '/4' in $wp. When cast to int, it returns 0 (Bless you, PHP). WP_Query calls trim( $page, '/' ) when setting its own query var. The few places that were checking page before posts were queried now have sanity checks, so that these changes work without flushing rewrites.

Adds/updates unit tests.

Props wonderboymusic, dd32.
See #11694.

Location:
trunk
Files:
1 added
5 edited

Legend:

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

    r34446 r34492  
    147147                $redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'page', 'feed', 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
    148148            }
     149        }
     150
     151        if ( get_query_var( 'page' ) && $wp_query->post &&
     152            false !== strpos( $wp_query->post->post_content, '<!--nextpage-->' ) ) {
     153            $redirect['path'] = rtrim( $redirect['path'], (int) get_query_var( 'page' ) . '/' );
     154            $redirect['query'] = remove_query_arg( 'page', $redirect['query'] );
     155            $redirect_url = get_permalink( $wp_query->post->ID );
    149156        }
    150157
     
    561568        if ( get_query_var( 'feed' ) )
    562569            return get_post_comments_feed_link( $post_id, get_query_var( 'feed' ) );
    563         elseif ( get_query_var( 'page' ) )
     570        elseif ( get_query_var( 'page' ) && 1 < get_query_var( 'page' ) )
    564571            return trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( get_query_var( 'page' ), 'single_paged' );
    565572        else
  • trunk/src/wp-includes/class-wp-rewrite.php

    r33751 r34492  
    10721072                    $sub2 .= '?$';
    10731073
    1074                     //post pagination, e.g. <permalink>/2/
    1075                     $match = $match . '(/[0-9]+)?/?$';
     1074                    // Post pagination, e.g. <permalink>/2/
     1075                    // Previously: '(/[0-9]+)?/?$', which produced '/2' for page.
     1076                    // When cast to int, returned 0.
     1077                    $match = $match . '(?:/([0-9]+))?/?$';
    10761078                    $query = $index . '?' . $query . '&page=' . $this->preg_index($num_toks + 1);
    10771079                } else { //not matching a permalink so this is a lot simpler
  • trunk/src/wp-includes/class-wp.php

    r34476 r34492  
    588588     */
    589589    public function handle_404() {
    590         global $wp_query;
     590        global $wp_query, $wp;
    591591
    592592        // If we've already issued a 404, bail.
     
    597597        if ( is_admin() || is_robots() || $wp_query->posts ) {
    598598
    599             // Only set X-Pingback for single posts.
     599            $success = true;
    600600            if ( is_singular() ) {
    601601                $p = clone $wp_query->post;
     602                // Only set X-Pingback for single posts that allow pings.
    602603                if ( $p && pings_open( $p ) ) {
    603604                    @header( 'X-Pingback: ' . get_bloginfo( 'pingback_url' ) );
    604605                }
    605             }
    606 
    607             status_header( 200 );
    608             return;
     606
     607                // check for paged content that exceeds the max number of pages
     608                $next = '<!--nextpage-->';
     609                if ( $p && false !== strpos( $p->post_content, $next ) && ! empty( $wp->query_vars['page'] ) ) {
     610                    $page = trim( $wp->query_vars['page'], '/' );
     611                    $success = (int) $page <= ( substr_count( $p->post_content, $next ) + 1 );
     612                }
     613            }
     614
     615            if ( $success ) {
     616                status_header( 200 );
     617                return;
     618            }
    609619        }
    610620
  • trunk/src/wp-includes/rewrite-functions.php

    r33751 r34492  
    257257        $maybe_page = $query_vars['day'];
    258258    }
     259    // Bug found in #11694 - 'page' was returning '/4'
     260    $maybe_page = (int) trim( $maybe_page, '/' );
    259261
    260262    $post_page_count = substr_count( $post->post_content, '<!--nextpage-->' ) + 1;
  • trunk/tests/phpunit/tests/canonical.php

    r34234 r34492  
    9797            array( '/post-format-test-au/', '/2008/06/02/post-format-test-audio/'),
    9898
    99             array( '/2008/09/03/images-test/3/', array( 'url' => '/2008/09/03/images-test/3/', 'qv' => array( 'name' => 'images-test', 'year' => '2008', 'monthnum' => '09', 'day' => '03', 'page' => '/3' ) ) ), // page = /3 ?!
     99            array( '/2008/09/03/images-test/3/', array( 'url' => '/2008/09/03/images-test/3/', 'qv' => array( 'name' => 'images-test', 'year' => '2008', 'monthnum' => '09', 'day' => '03', 'page' => '3' ) ) ),
    100100            array( '/2008/09/03/images-test/?page=3', '/2008/09/03/images-test/3/' ),
    101101            array( '/2008/09/03/images-te?page=3', '/2008/09/03/images-test/3/' ),
Note: See TracChangeset for help on using the changeset viewer.