Make WordPress Core

Changeset 54569

Timestamp:
10/17/2022 06:11:47 PM (22 months ago)
Author:
SergeyBiryukov
Message:

Grouped backports to the 4.9 branch.

  • Posts, Post types: Apply KSES to post-by-email content,
  • General: Validate host on "Are you sure?" screen,
  • Posts, Post types: Remove emails from post-by-email logs,
  • Media: Refactor search by filename within the admin,
  • Pings/trackbacks: Apply KSES to all trackbacks,
  • Comments: Apply kses when editing comments,
  • Customize: Escape blogname option in underscores templates,
  • REST API: Lockdown post parameter of the terms endpoint,
  • Mail: Reset PHPMailer properties between use,
  • Query: Validate relation in WP_Date_Query,
  • Widgets: Escape RSS error messages for display.

Merges [54521], [54522], [54523], [54524], [54525], [54526], [54527], [54528], [54529], [54530], [54541] to the 4.9 branch.
Props voldemortensen, johnbillion, paulkevan, peterwilsoncc, xknown, dd32, audrasjb, martinkrcho, vortfu, davidbaumwald, tykoted, timothyblynjacobs, johnjamesjacoby, ehtis, matveb, talldanwp.

Location:
branches/4.9
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • branches/4.9

  • branches/4.9/src/wp-admin/includes/ajax-actions.php

    r45943 r54569  
    24722472    // Filter query clauses to include filenames.
    24732473    if ( isset( $query['s'] ) ) {
    2474         add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
     2474        add_filter( '' );
    24752475    }
    24762476
  • branches/4.9/src/wp-admin/includes/post.php

    r44053 r54569  
    11751175    // Filter query clauses to include filenames.
    11761176    if ( isset( $q['s'] ) ) {
    1177         add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
     1177        add_filter( '' );
    11781178    }
    11791179
  • branches/4.9/src/wp-includes/class-wp-query.php

    r47648 r54569  
    438438    private $compat_methods = array( 'init_query_flags', 'parse_tax_query' );
    439439
     440
     441
     442
     443
     444
     445
     446
    440447    /**
    441448     * Resets query flags to false.
     
    12991306
    13001307            $like = $n . $wpdb->esc_like( $term ) . $n;
    1301             $search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
     1308
     1309            if ( ! empty( $this->allow_query_attachment_by_filename ) ) {
     1310                $search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s) $andor_op (sq1.meta_value $like_op %s))", $like, $like, $like, $like );
     1311            } else {
     1312                $search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
     1313            }
    13021314            $searchand = ' AND ';
    13031315        }
     
    16351647        $q = $this->fill_query_vars($q);
    16361648
     1649
     1650
     1651
     1652
     1653
     1654
     1655
     1656
     1657
     1658
    16371659        // Parse meta query
    16381660        $this->meta_query = new WP_Meta_Query();
     
    20392061        }
    20402062
    2041         if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) {
     2063        if ( ! ) ) {
    20422064            $groupby = "{$wpdb->posts}.ID";
    20432065        }
     
    21112133        }
    21122134        $where .= $search . $whichauthor . $whichmimetype;
     2135
     2136
     2137
     2138
    21132139
    21142140        if ( ! empty( $this->meta_query->queries ) ) {
  • branches/4.9/src/wp-includes/comment.php

    r44845 r54569  
    21962196    }
    21972197
     2198
     2199
     2200
     2201
     2202
     2203
     2204
     2205
     2206
    21982207    // Escape data pulled from DB.
    21992208    $comment = wp_slash($comment);
     
    22052214
    22062215    $commentarr = wp_filter_comment( $commentarr );
     2216
     2217
     2218
     2219
    22072220
    22082221    // Now extract the merged array.
  • branches/4.9/src/wp-includes/customize/class-wp-customize-header-image-control.php

    r41935 r54569  
    104104
    105105            <button type="button" class="choice thumbnail"
    106                 data-customize-image-value="{{{data.header.url}}}"
     106                data-customize-image-value="{{}}"
    107107                data-customize-header-image-data="{{JSON.stringify(data.header)}}">
    108108                <span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>
    109                 <img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">
     109                <img src="{{>
    110110            </button>
    111111
  • branches/4.9/src/wp-includes/customize/class-wp-customize-site-icon-control.php

    r41162 r54569  
    6767                                <img src="{{ data.attachment.sizes.full ? data.attachment.sizes.full.url : data.attachment.url }}" alt="<?php esc_attr_e( 'Preview as a browser icon' ); ?>"/>
    6868                            </div>
    69                             <span class="browser-title" aria-hidden="true"><?php bloginfo( 'name' ); ?></span>
     69                            <span class="browser-title" aria-hidden="true"><?php ); ?></span>
    7070                        </div>
    7171                        <img class="app-icon-preview" src="{{ data.attachment.sizes.full ? data.attachment.sizes.full.url : data.attachment.url }}" alt="<?php esc_attr_e( 'Preview as an app icon' ); ?>"/>
  • branches/4.9/src/wp-includes/date.php

    r41162 r54569  
    146146     */
    147147    public function __construct( $date_query, $default_column = 'post_date' ) {
    148         if ( isset( $date_query['relation'] ) && 'OR' === strtoupper( $date_query['relation'] ) ) {
    149             $this->relation = 'OR';
     148        if ( isset( $date_query['relation'] ) ) {
     149            $this->relation = ;
    150150        } else {
    151151            $this->relation = 'AND';
     
    225225            $this->validate_date_values( $queries );
    226226        }
     227
     228
     229
    227230
    228231        foreach ( $queries as $key => $q ) {
     
    9991002        return $wpdb->prepare( "DATE_FORMAT( $column, %s ) $compare %f", $format, $time );
    10001003    }
     1004
     1005
     1006
     1007
     1008
     1009
     1010
     1011
     1012
     1013
     1014
     1015
     1016
     1017
     1018
     1019
    10011020}
  • branches/4.9/src/wp-includes/deprecated.php

    r41787 r54569  
    39453945    }
    39463946}
     3947
     3948
     3949
     3950
     3951
     3952
     3953
     3954
     3955
     3956
     3957
     3958
     3959
     3960
     3961
     3962
     3963
     3964
  • branches/4.9/src/wp-includes/functions.php

    r46493 r54569  
    23782378            if ( $type !== $real_mime ) {
    23792379                /*
    2380                  * Everything else including image/* and application/*: 
     2380                 * Everything else including image/* and application/*:
    23812381                 * If the real content type doesn't match the file extension, assume it's dangerous.
    23822382                 */
     
    23872387    }
    23882388
    2389     // The mime type must be allowed 
     2389    // The mime type must be allowed
    23902390    if ( $type ) {
    23912391        $allowed = get_allowed_mime_types();
     
    26612661        $html = __( 'The link you followed has expired.' );
    26622662        if ( wp_get_referer() ) {
    2663             $html .= '</p><p>';
    2664             $html .= sprintf( '<a href="%s">%s</a>',
    2665                 esc_url( remove_query_arg( 'updated', wp_get_referer() ) ),
     2663            $wp_http_referer = remove_query_arg( 'updated', wp_get_referer() );
     2664            $wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) );
     2665            $html           .= '</p><p>';
     2666            $html           .= sprintf(
     2667                '<a href="%s">%s</a>',
     2668                esc_url( $wp_http_referer ),
    26662669                __( 'Please try again.' )
    26672670            );
  • branches/4.9/src/wp-includes/media-template.php

    r43948 r54569  
    12531253                <img id="preview-favicon" src="{{ data.url }}" alt="<?php esc_attr_e( 'Preview as a browser icon' ); ?>"/>
    12541254            </div>
    1255             <span class="browser-title" aria-hidden="true"><?php bloginfo( 'name' ); ?></span>
     1255            <span class="browser-title" aria-hidden="true"><?php ); ?></span>
    12561256        </div>
    12571257
  • branches/4.9/src/wp-includes/pluggable.php

    r47967 r54569  
    313313    $phpmailer->clearCustomHeaders();
    314314    $phpmailer->clearReplyTos();
     315
     316
    315317
    316318    // From email and name
  • branches/4.9/src/wp-includes/post.php

    r52474 r54569  
    17061706    }
    17071707
    1708     return $post_type->publicly_queryable || ( $post_type->_builtin && $post_type->public );
     1708    if ( ! is_object( $post_type ) ) {
     1709        return false;
     1710    }
     1711
     1712    $is_viewable = $post_type->publicly_queryable || ( $post_type->_builtin && $post_type->public );
     1713
     1714    /**
     1715     * Filters whether a post type is considered "viewable".
     1716     *
     1717     * The returned filtered value must be a boolean type to ensure
     1718     * `is_post_type_viewable()` only returns a boolean. This strictness
     1719     * is by design to maintain backwards-compatibility and guard against
     1720     * potential type errors in PHP 8.1+. Non-boolean values (even falsey
     1721     * and truthy values) will result in the function returning false.
     1722     *
     1723     * @since 5.9.0
     1724     *
     1725     * @param bool         $is_viewable Whether the post type is "viewable" (strict type).
     1726     * @param WP_Post_Type $post_type   Post type object.
     1727     */
     1728    return true === apply_filters( 'is_post_type_viewable', $is_viewable, $post_type );
     1729}
     1730
     1731/**
     1732 * Determines whether a post status is considered "viewable".
     1733 *
     1734 * For built-in post statuses such as publish and private, the 'public' value will be evaluated.
     1735 * For all others, the 'publicly_queryable' value will be used.
     1736 *
     1737 * @since 5.7.0
     1738 * @since 5.9.0 Added `is_post_status_viewable` hook to filter the result.
     1739 *
     1740 * @param string|stdClass $post_status Post status name or object.
     1741 * @return bool Whether the post status should be considered viewable.
     1742 */
     1743function is_post_status_viewable( $post_status ) {
     1744    if ( is_scalar( $post_status ) ) {
     1745        $post_status = get_post_status_object( $post_status );
     1746
     1747        if ( ! $post_status ) {
     1748            return false;
     1749        }
     1750    }
     1751
     1752    if (
     1753        ! is_object( $post_status ) ||
     1754        $post_status->internal ||
     1755        $post_status->protected
     1756    ) {
     1757        return false;
     1758    }
     1759
     1760    $is_viewable = $post_status->publicly_queryable || ( $post_status->_builtin && $post_status->public );
     1761
     1762    /**
     1763     * Filters whether a post status is considered "viewable".
     1764     *
     1765     * The returned filtered value must be a boolean type to ensure
     1766     * `is_post_status_viewable()` only returns a boolean. This strictness
     1767     * is by design to maintain backwards-compatibility and guard against
     1768     * potential type errors in PHP 8.1+. Non-boolean values (even falsey
     1769     * and truthy values) will result in the function returning false.
     1770     *
     1771     * @since 5.9.0
     1772     *
     1773     * @param bool     $is_viewable Whether the post status is "viewable" (strict type).
     1774     * @param stdClass $post_status Post status object.
     1775     */
     1776    return true === apply_filters( 'is_post_status_viewable', $is_viewable, $post_status );
     1777}
     1778
     1779/**
     1780 * Determines whether a post is publicly viewable.
     1781 *
     1782 * Posts are considered publicly viewable if both the post status and post type
     1783 * are viewable.
     1784 *
     1785 * @since 5.7.0
     1786 *
     1787 * @param int|WP_Post|null $post Optional. Post ID or post object. Defaults to global $post.
     1788 * @return bool Whether the post is publicly viewable.
     1789 */
     1790function is_post_publicly_viewable( $post = null ) {
     1791    $post = get_post( $post );
     1792
     1793    if ( ! $post ) {
     1794        return false;
     1795    }
     1796
     1797    $post_type   = get_post_type( $post );
     1798    $post_status = get_post_status( $post );
     1799
     1800    return is_post_type_viewable( $post_type ) && is_post_status_viewable( $post_status );
    17091801}
    17101802
     
    64566548    return $post_name;
    64576549}
    6458 
    6459 /**
    6460  * Filter the SQL clauses of an attachment query to include filenames.
    6461  *
    6462  * @since 4.7.0
    6463  * @access private
    6464  *
    6465  * @global wpdb $wpdb WordPress database abstraction object.
    6466  *
    6467  * @param array $clauses An array including WHERE, GROUP BY, JOIN, ORDER BY,
    6468  *                       DISTINCT, fields (SELECT), and LIMITS clauses.
    6469  * @return array The modified clauses.
    6470  */
    6471 function _filter_query_attachment_filenames( $clauses ) {
    6472     global $wpdb;
    6473     remove_filter( 'posts_clauses', __FUNCTION__ );
    6474 
    6475     // Add a LEFT JOIN of the postmeta table so we don't trample existing JOINs.
    6476     $clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )";
    6477 
    6478     $clauses['groupby'] = "{$wpdb->posts}.ID";
    6479 
    6480     $clauses['where'] = preg_replace(
    6481         "/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/",
    6482         "$0 OR ( sq1.meta_value $1 $2 )",
    6483         $clauses['where'] );
    6484 
    6485     return $clauses;
    6486 }
  • branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php

    r43530 r54569  
    4949        // Filter query clauses to include filenames.
    5050        if ( isset( $query_args['s'] ) ) {
    51             add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
     51            add_filter( '' );
    5252        }
    5353
  • branches/4.9/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php

    r43637 r54569  
    128128
    129129    /**
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
    130159     * Checks if a request has access to read terms in the specified taxonomy.
    131160     *
     
    137166    public function get_items_permissions_check( $request ) {
    138167        $tax_obj = get_taxonomy( $this->taxonomy );
     168
    139169        if ( ! $tax_obj || ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) {
    140170            return false;
    141171        }
     172
    142173        if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->edit_terms ) ) {
    143             return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) );
    144         }
     174            return new WP_Error(
     175                'rest_forbidden_context',
     176                __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ),
     177                array( 'status' => rest_authorization_required_code() )
     178            );
     179        }
     180
     181        if ( ! empty( $request['post'] ) ) {
     182            $post = get_post( $request['post'] );
     183
     184            if ( ! $post ) {
     185                return new WP_Error(
     186                    'rest_post_invalid_id',
     187                    __( 'Invalid post ID.' ),
     188                    array(
     189                        'status' => 400,
     190                    )
     191                );
     192            }
     193
     194            if ( ! $this->check_read_terms_permission_for_post( $post, $request ) ) {
     195                return new WP_Error(
     196                    'rest_forbidden_context',
     197                    __( 'Sorry, you are not allowed to view terms for this post.' ),
     198                    array(
     199                        'status' => rest_authorization_required_code(),
     200                    )
     201                );
     202            }
     203        }
     204
    145205        return true;
    146206    }
  • branches/4.9/src/wp-includes/widgets.php

    r43302 r54569  
    13971397    if ( is_wp_error($rss) ) {
    13981398        if ( is_admin() || current_user_can('manage_options') )
    1399             echo '<p><strong>' . __( 'RSS Error:' ) . '</strong> ' . $rss->get_error_message() . '</p>';
     1399            echo '<p><strong>' . __( 'RSS Error:' ) . '</strong> ' . ) . '</p>';
    14001400        return;
    14011401    }
     
    15061506
    15071507    if ( ! empty( $args['error'] ) ) {
    1508         echo '<p class="widget-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . $args['error'] . '</p>';
     1508        echo '<p class="widget-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . . '</p>';
    15091509    }
    15101510
  • branches/4.9/src/wp-mail.php

    r39772 r54569  
    6060    wp_die( __('There doesn&#8217;t seem to be any new mail.') );
    6161}
     62
     63
     64
    6265
    6366for ( $i = 1; $i <= $count; $i++ ) {
     
    125128                $author = sanitize_email($author);
    126129                if ( is_email($author) ) {
    127                     /* translators: Post author email address */
    128                     echo '<p>' . sprintf(__('Author is %s'), $author) . '</p>';
    129130                    $userdata = get_user_by('email', $author);
    130131                    if ( ! empty( $userdata ) ) {
    131                         $post_author = $userdata->ID;
     132                        $post_author = $userdata->ID;
    132133                        $author_found = true;
    133134                    }
  • branches/4.9/src/wp-trackback.php

    r41980 r54569  
    1313    wp( array( 'tb' => '1' ) );
    1414}
     15
     16
     17
    1518
    1619/**
  • branches/4.9/tests/phpunit/tests/query/search.php

    r38844 r54569  
    371371
    372372        add_post_meta( $attachment, '_wp_attached_file', 'some-image1.png', true );
    373         add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
     373        add_filter( '' );
    374374
    375375        // Pass post_type a string value.
     
    397397
    398398        add_post_meta( $attachment, '_wp_attached_file', 'some-image2.png', true );
    399         add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
     399        add_filter( '' );
    400400
    401401        // Pass post_type an array value.
     
    448448        add_post_meta( $attachment, '_wp_attached_file', 'some-image4.png', true );
    449449        add_post_meta( $attachment, '_test_meta_key', 'value', true );
    450         add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
     450        add_filter( '' );
    451451
    452452        // Pass post_type a string value.
     
    484484
    485485        add_post_meta( $attachment, '_wp_attached_file', 'some-image5.png', true );
    486         add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
     486        add_filter( '' );
    487487
    488488        // Pass post_type a string value.
     
    507507     * @ticket 22744
    508508     */
    509     public function test_filter_query_attachment_filenames_unhooks_itself() {
    510         add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
    511 
    512         apply_filters( 'posts_clauses', array(
    513             'where'    => '',
    514             'groupby'  => '',
    515             'join'     => '',
    516             'orderby'  => '',
    517             'distinct' => '',
    518             'fields'   => '',
    519             'limit'    => '',
    520         ) );
    521 
    522         $result = has_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
    523 
    524         $this->assertFalse( $result );
     509    public function test_wp_query_removes_filter_wp_allow_query_attachment_by_filename() {
     510        $attachment = self::factory()->post->create(
     511            array(
     512                'post_type'    => 'attachment',
     513                'post_status'  => 'publish',
     514                'post_title'   => 'bar foo',
     515                'post_content' => 'foo bar',
     516                'post_excerpt' => 'This post has foo',
     517            )
     518        );
     519
     520        add_post_meta( $attachment, '_wp_attached_file', 'some-image1.png', true );
     521        add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' );
     522
     523        $q = new WP_Query(
     524            array(
     525                's'           => 'image1',
     526                'fields'      => 'ids',
     527                'post_type'   => 'attachment',
     528                'post_status' => 'inherit',
     529            )
     530        );
     531
     532        $this->assertSame( array( $attachment ), $q->posts );
     533
     534        /*
     535         * WP_Query should have removed the wp_allow_query_attachment_by_filename filter
     536         * and thus not match the attachment created above
     537         */
     538        $q->get_posts();
     539        $this->assertEmpty( $q->posts );
    525540    }
    526541
  • branches/4.9/tests/phpunit/tests/rest-api/rest-comments-controller.php

    r43445 r54569  
    26052605                'author_name'       => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
    26062606                'author_user_agent' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     2607
    26072608            ), array(
    26082609                'content' => array(
     
    26122613                'author_name'       => 'div strong',
    26132614                'author_user_agent' => 'div strong',
     2615
    26142616            ) );
    26152617        } else {
     
    26192621                'author_name'       => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
    26202622                'author_user_agent' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     2623
    26212624            ), array(
    26222625                'content' => array(
     
    26262629                'author_name'       => 'div strong',
    26272630                'author_user_agent' => 'div strong',
     2631
    26282632            ) );
    26292633        }
     
    26372641            'author_name'       => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
    26382642            'author_user_agent' => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     2643
    26392644        ), array(
    26402645            'content' => array(
     
    26442649            'author_name'       => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
    26452650            'author_user_agent' => '\\\&\\\ &amp; &invalid; &lt; &lt; &amp;lt;',
     2651
    26462652        ) );
    26472653    }
     
    26542660            'author_name'       => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
    26552661            'author_user_agent' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     2662
    26562663        ), array(
    26572664            'content' => array(
     
    26612668            'author_name'       => 'div strong',
    26622669            'author_user_agent' => 'div strong',
     2670
    26632671        ) );
    26642672    }
Note: See TracChangeset for help on using the changeset viewer.