Make WordPress Core

Changeset 56864

Timestamp:
10/12/2023 02:50:31 PM (9 months ago)
Author:
davidbaumwald
Message:

Grouped backports to the 4.8 branch.

  • Comments: Prevent users who can not see a post from seeing comments on it.
  • Shortcodes: Restrict media shortcode ajax to certain type.
  • REST API: Ensure no-cache headers are sent when methods are overridden.
  • REST API: Limit search_columns for users without list_users.
  • Prevent unintended behavior when certain objects are unserialized.

Merges [56834], [56835], [56836], [56838], and [56840] to the 4.8 branch.
Props xknown, jorbin, joehoyle, timothyblynjacobs, peterwilsoncc, ehtis, tykoted, antpb, rmccue.

Location:
branches/4.8/src
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • branches/4.8/src/wp-admin/includes/ajax-actions.php

    r55786 r56864  
    31133113    $shortcode = wp_unslash( $_POST['shortcode'] );
    31143114
     3115
     3116
     3117
     3118
     3119
     3120
     3121
     3122
     3123
     3124
     3125
     3126
     3127
     3128
     3129
     3130
    31153131    if ( ! empty( $_POST['post_ID'] ) ) {
    31163132        $post = get_post( (int) $_POST['post_ID'] );
     
    31193135    // the embed shortcode requires a post
    31203136    if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
    3121         if ( 'embed' === $shortcode ) {
     3137        if ( ) {
    31223138            wp_send_json_error();
    31233139        }
  • branches/4.8/src/wp-admin/includes/class-wp-comments-list-table.php

    r41023 r56864  
    500500        $this->user_can = current_user_can( 'edit_comment', $comment->comment_ID );
    501501
     502
     503
     504
     505
     506
     507
     508
     509
     510
     511
     512
     513
     514
    502515        echo "<tr id='comment-$comment->comment_ID' class='$the_comment_class'>";
    503516        $this->single_row_columns( $comment );
  • branches/4.8/src/wp-admin/includes/class-wp-list-table.php

    r39600 r56864  
    655655        $pending_phrase = sprintf( _n( '%s pending comment', '%s pending comments', $pending_comments ), $pending_comments_number );
    656656
    657         // No comments at all.
     657        $post_object   = get_post( $post_id );
     658        $edit_post_cap = $post_object ? 'edit_post' : 'edit_posts';
     659        if (
     660            current_user_can( $edit_post_cap, $post_id ) ||
     661            (
     662                empty( $post_object->post_password ) &&
     663                current_user_can( 'read_post', $post_id )
     664            )
     665        ) {
     666            // The user has access to the post and thus can see comments
     667        } else {
     668            return false;
     669        }
     670
    658671        if ( ! $approved_comments && ! $pending_comments ) {
    659672            printf( '<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>',
  • branches/4.8/src/wp-admin/includes/dashboard.php

    r40866 r56864  
    920920
    921921        echo '<ul id="the-comment-list" data-wp-lists="list:comment">';
    922         foreach ( $comments as $comment )
    923             _wp_dashboard_recent_comments_row( $comment );
     922        foreach ( $comments as $comment ) {
     923            $comment_post = get_post( $comment->comment_post_ID );
     924            if (
     925                current_user_can( 'edit_post', $comment->comment_post_ID ) ||
     926                (
     927                    empty( $comment_post->post_password ) &&
     928                    current_user_can( 'read_post', $comment->comment_post_ID )
     929                )
     930            ) {
     931                _wp_dashboard_recent_comments_row( $comment );
     932            }
     933        }
    924934        echo '</ul>';
    925935
  • branches/4.8/src/wp-includes/Requests/Hooks.php

    r38049 r56864  
    6666        return true;
    6767    }
     68
     69
     70
     71
    6872}
  • branches/4.8/src/wp-includes/Requests/IRI.php

    r38727 r56864  
    704704    }
    705705
     706
     707
     708
     709
     710
     711
     712
     713
     714
     715
     716
     717
     718
     719
    706720    /**
    707721     * Set the entire IRI. Returns true on success, false on failure (if there
  • branches/4.8/src/wp-includes/Requests/Session.php

    r38049 r56864  
    228228    }
    229229
     230
     231
     232
     233
    230234    /**
    231235     * Merge a request's data with the default data
  • branches/4.8/src/wp-includes/class-wp-theme.php

    r40301 r56864  
    548548
    549549    /**
     550
     551
     552
     553
     554
     555
     556
     557
     558
     559
     560
     561
     562
     563
     564
     565
     566
     567
     568
     569
     570
     571
    550572     * Adds theme data to cache.
    551573     *
     
    15151537        return strnatcasecmp( $a->display( 'Name', false, true ), $b->display( 'Name', false, true ) );
    15161538    }
     1539
     1540
     1541
     1542
     1543
     1544
     1545
     1546
     1547
     1548
     1549
     1550
    15171551}
  • branches/4.8/src/wp-includes/media.php

    r55786 r56864  
    16901690        }
    16911691    } elseif ( ! empty( $atts['exclude'] ) ) {
     1692
    16921693        $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $atts['exclude'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
    16931694    } else {
     1695
    16941696        $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
     1697
     1698
     1699
     1700
     1701
     1702
     1703
     1704
     1705
     1706
     1707
    16951708    }
    16961709
     
    19942007    }
    19952008
     2009
     2010
     2011
     2012
     2013
     2014
     2015
     2016
     2017
    19962018    if ( empty( $attachments ) ) {
    19972019        return '';
  • branches/4.8/src/wp-includes/rest-api.php

    r46494 r56864  
    749749
    750750    if ( ! $result ) {
     751
    751752        return new WP_Error( 'rest_cookie_invalid_nonce', __( 'Cookie nonce is invalid' ), array( 'status' => 403 ) );
    752753    }
  • branches/4.8/src/wp-includes/rest-api/class-wp-rest-server.php

    r41093 r56864  
    244244
    245245        /**
    246          * Send nocache headers on authenticated requests.
     246         * .
    247247         *
    248248         * @since 4.4.0
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
    249371         *
    250372         * @param bool $rest_send_nocache_headers Whether to send no-cache headers.
    251373         */
    252374        $send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() );
    253         if ( $send_no_cache_headers ) {
     375
     376        // send no cache headers if the $send_no_cache_headers is true
     377        // OR if the HTTP_X_HTTP_METHOD_OVERRIDE is used but resulted a 4xx response code.
     378        if ( $send_no_cache_headers || ( true === $method_overridden && strpos( $code, '4' ) === 0 ) ) {
    254379            foreach ( wp_get_nocache_headers() as $header => $header_value ) {
    255380                if ( empty( $header_value ) ) {
     
    260385            }
    261386        }
    262 
    263         /**
    264          * Filters whether the REST API is enabled.
    265          *
    266          * @since 4.4.0
    267          * @deprecated 4.7.0 Use the rest_authentication_errors filter to restrict access to the API
    268          *
    269          * @param bool $rest_enabled Whether the REST API is enabled. Default true.
    270          */
    271         apply_filters_deprecated( 'rest_enabled', array( true ), '4.7.0', 'rest_authentication_errors',
    272             __( 'The REST API can no longer be completely disabled, the rest_authentication_errors filter can be used to restrict access to the API, instead.' )
    273         );
    274 
    275         /**
    276          * Filters whether jsonp is enabled.
    277          *
    278          * @since 4.4.0
    279          *
    280          * @param bool $jsonp_enabled Whether jsonp is enabled. Default true.
    281          */
    282         $jsonp_enabled = apply_filters( 'rest_jsonp_enabled', true );
    283 
    284         $jsonp_callback = null;
    285 
    286         if ( isset( $_GET['_jsonp'] ) ) {
    287             if ( ! $jsonp_enabled ) {
    288                 echo $this->json_error( 'rest_callback_disabled', __( 'JSONP support is disabled on this site.' ), 400 );
    289                 return false;
    290             }
    291 
    292             $jsonp_callback = $_GET['_jsonp'];
    293             if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) {
    294                 echo $this->json_error( 'rest_callback_invalid', __( 'Invalid JSONP callback function.' ), 400 );
    295                 return false;
    296             }
    297         }
    298 
    299         if ( empty( $path ) ) {
    300             if ( isset( $_SERVER['PATH_INFO'] ) ) {
    301                 $path = $_SERVER['PATH_INFO'];
    302             } else {
    303                 $path = '/';
    304             }
    305         }
    306 
    307         $request = new WP_REST_Request( $_SERVER['REQUEST_METHOD'], $path );
    308 
    309         $request->set_query_params( wp_unslash( $_GET ) );
    310         $request->set_body_params( wp_unslash( $_POST ) );
    311         $request->set_file_params( $_FILES );
    312         $request->set_headers( $this->get_headers( wp_unslash( $_SERVER ) ) );
    313         $request->set_body( $this->get_raw_data() );
    314 
    315         /*
    316          * HTTP method override for clients that can't use PUT/PATCH/DELETE. First, we check
    317          * $_GET['_method']. If that is not set, we check for the HTTP_X_HTTP_METHOD_OVERRIDE
    318          * header.
    319          */
    320         if ( isset( $_GET['_method'] ) ) {
    321             $request->set_method( $_GET['_method'] );
    322         } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) {
    323             $request->set_method( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] );
    324         }
    325 
    326         $result = $this->check_authentication();
    327 
    328         if ( ! is_wp_error( $result ) ) {
    329             $result = $this->dispatch( $request );
    330         }
    331 
    332         // Normalize to either WP_Error or WP_REST_Response...
    333         $result = rest_ensure_response( $result );
    334 
    335         // ...then convert WP_Error across.
    336         if ( is_wp_error( $result ) ) {
    337             $result = $this->error_to_response( $result );
    338         }
    339 
    340         /**
    341          * Filters the API response.
    342          *
    343          * Allows modification of the response before returning.
    344          *
    345          * @since 4.4.0
    346          * @since 4.5.0 Applied to embedded responses.
    347          *
    348          * @param WP_HTTP_Response $result  Result to send to the client. Usually a WP_REST_Response.
    349          * @param WP_REST_Server   $this    Server instance.
    350          * @param WP_REST_Request  $request Request used to generate the response.
    351          */
    352         $result = apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request );
    353 
    354         // Wrap the response in an envelope if asked for.
    355         if ( isset( $_GET['_envelope'] ) ) {
    356             $result = $this->envelope_response( $result, isset( $_GET['_embed'] ) );
    357         }
    358 
    359         // Send extra data from response objects.
    360         $headers = $result->get_headers();
    361         $this->send_headers( $headers );
    362 
    363         $code = $result->get_status();
    364         $this->set_status( $code );
    365 
    366         /**
    367          * Filters whether the request has already been served.
    368          *
    369          * Allow sending the request manually - by returning true, the API result
    370          * will not be sent to the client.
    371          *
    372          * @since 4.4.0
    373          *
    374          * @param bool             $served  Whether the request has already been served.
    375          *                                           Default false.
    376          * @param WP_HTTP_Response $result  Result to send to the client. Usually a WP_REST_Response.
    377          * @param WP_REST_Request  $request Request used to generate the response.
    378          * @param WP_REST_Server   $this    Server instance.
    379          */
    380         $served = apply_filters( 'rest_pre_serve_request', false, $result, $request, $this );
    381387
    382388        if ( ! $served ) {
  • branches/4.8/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php

    r40378 r56864  
    261261
    262262        if ( ! empty( $prepared_args['search'] ) ) {
     263
     264
     265
    263266            $prepared_args['search'] = '*' . $prepared_args['search'] . '*';
    264267        }
  • branches/4.8/src/wp-includes/shortcodes.php

    r39665 r56864  
    186186
    187187/**
    188  * Search content for shortcodes and filter shortcodes through their hooks.
     188 * Returns a list of registered shortcode names found in the given content.
     189 *
     190 * Example usage:
     191 *
     192 *     get_shortcode_tags_in_content( '[audio src="file.mp3"][/audio] [foo] [gallery ids="1,2,3"]' );
     193 *     // array( 'audio', 'gallery' )
     194 *
     195 * @since 6.3.2
     196 *
     197 * @param string $content The content to check.
     198 * @return string[] An array of registered shortcode names found in the content.
     199 */
     200function get_shortcode_tags_in_content( $content ) {
     201    if ( false === strpos( $content, '[' ) ) {
     202        return array();
     203    }
     204
     205    preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER );
     206    if ( empty( $matches ) ) {
     207        return array();
     208    }
     209
     210    $tags = array();
     211    foreach ( $matches as $shortcode ) {
     212        $tags[] = $shortcode[2];
     213
     214        if ( ! empty( $shortcode[5] ) ) {
     215            $deep_tags = get_shortcode_tags_in_content( $shortcode[5] );
     216            if ( ! empty( $deep_tags ) ) {
     217                $tags = array_merge( $tags, $deep_tags );
     218            }
     219        }
     220    }
     221
     222    return $tags;
     223}
     224
     225/**
     226 * Searches content for shortcodes and filter shortcodes through their hooks.
    189227 *
    190228 * If there are no shortcode tags defined, then the content will be returned
Note: See TracChangeset for help on using the changeset viewer.