Changeset 56895
- Timestamp:
- 10/12/2023 04:07:43 PM (14 months ago)
- Location:
- branches/6.2
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/6.2
- Property svn:mergeinfo changed
/trunk merged: 56833-56838
- Property svn:mergeinfo changed
-
branches/6.2/src/wp-admin/includes/ajax-actions.php
r55769 r56895 3856 3856 $shortcode = wp_unslash( $_POST['shortcode'] ); 3857 3857 3858 // Only process previews for media related shortcodes: 3859 $found_shortcodes = get_shortcode_tags_in_content( $shortcode ); 3860 $media_shortcodes = array( 3861 'audio', 3862 'embed', 3863 'playlist', 3864 'video', 3865 'gallery', 3866 ); 3867 3868 $other_shortcodes = array_diff( $found_shortcodes, $media_shortcodes ); 3869 3870 if ( ! empty( $other_shortcodes ) ) { 3871 wp_send_json_error(); 3872 } 3873 3858 3874 if ( ! empty( $_POST['post_ID'] ) ) { 3859 3875 $post = get_post( (int) $_POST['post_ID'] ); … … 3862 3878 // The embed shortcode requires a post. 3863 3879 if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) { 3864 if ( 'embed' === $shortcode) {3880 if ( in_array( 'embed', $found_shortcodes, true ) ) { 3865 3881 wp_send_json_error(); 3866 3882 } -
branches/6.2/src/wp-admin/includes/class-wp-comments-list-table.php
r55276 r56895 641 641 642 642 $this->user_can = current_user_can( 'edit_comment', $comment->comment_ID ); 643 644 $edit_post_cap = $post ? 'edit_post' : 'edit_posts'; 645 if ( 646 current_user_can( $edit_post_cap, $comment->comment_post_ID ) || 647 ( 648 empty( $post->post_password ) && 649 current_user_can( 'read_post', $comment->comment_post_ID ) 650 ) 651 ) { 652 // The user has access to the post 653 } else { 654 return false; 655 } 643 656 644 657 echo "<tr id='comment-$comment->comment_ID' class='$the_comment_class'>"; -
branches/6.2/src/wp-admin/includes/class-wp-list-table.php
r55293 r56895 818 818 $pending_comments_number 819 819 ); 820 821 $post_object = get_post( $post_id ); 822 $edit_post_cap = $post_object ? 'edit_post' : 'edit_posts'; 823 if ( 824 current_user_can( $edit_post_cap, $post_id ) || 825 ( 826 empty( $post_object->post_password ) && 827 current_user_can( 'read_post', $post_id ) 828 ) 829 ) { 830 // The user has access to the post and thus can see comments 831 } else { 832 return false; 833 } 820 834 821 835 if ( ! $approved_comments && ! $pending_comments ) { -
branches/6.2/src/wp-admin/includes/dashboard.php
r55576 r56895 1102 1102 echo '<ul id="the-comment-list" data-wp-lists="list:comment">'; 1103 1103 foreach ( $comments as $comment ) { 1104 _wp_dashboard_recent_comments_row( $comment ); 1104 1105 $comment_post = get_post( $comment->comment_post_ID ); 1106 if ( 1107 current_user_can( 'edit_post', $comment->comment_post_ID ) || 1108 ( 1109 empty( $comment_post->post_password ) && 1110 current_user_can( 'read_post', $comment->comment_post_ID ) 1111 ) 1112 ) { 1113 _wp_dashboard_recent_comments_row( $comment ); 1114 } 1105 1115 } 1106 1116 echo '</ul>'; -
branches/6.2/src/wp-admin/includes/user.php
r55283 r56895 614 614 * @since 5.6.0 615 615 * @since 6.2.0 Allow insecure HTTP connections for the local environment. 616 * @since 6.3.2 Validates the success and reject URLs to prevent javascript pseudo protocol being executed. 616 617 * 617 618 * @param array $request { … … 627 628 */ 628 629 function wp_is_authorize_application_password_request_valid( $request, $user ) { 629 $error = new WP_Error(); 630 $is_local = 'local' === wp_get_environment_type(); 631 632 if ( ! empty( $request['success_url'] ) ) { 633 $scheme = wp_parse_url( $request['success_url'], PHP_URL_SCHEME ); 634 635 if ( 'http' === $scheme && ! $is_local ) { 630 $error = new WP_Error(); 631 632 if ( isset( $request['success_url'] ) ) { 633 $validated_success_url = wp_is_authorize_application_redirect_url_valid( $request['success_url'] ); 634 if ( is_wp_error( $validated_success_url ) ) { 636 635 $error->add( 637 'invalid_redirect_scheme',638 __( 'The success URL must be served over a secure connection.')636 $validated_success_url->get_error_code(), 637 $validated_success_url->get_error_message() 639 638 ); 640 639 } 641 640 } 642 641 643 if ( ! empty( $request['reject_url'] ) ) { 644 $scheme = wp_parse_url( $request['reject_url'], PHP_URL_SCHEME ); 645 646 if ( 'http' === $scheme && ! $is_local ) { 642 if ( isset( $request['reject_url'] ) ) { 643 $validated_reject_url = wp_is_authorize_application_redirect_url_valid( $request['reject_url'] ); 644 if ( is_wp_error( $validated_reject_url ) ) { 647 645 $error->add( 648 'invalid_redirect_scheme',649 __( 'The rejection URL must be served over a secure connection.')646 $validated_reject_url->get_error_code(), 647 $validated_reject_url->get_error_message() 650 648 ); 651 649 } … … 676 674 return true; 677 675 } 676 677 /** 678 * Validates the redirect URL protocol scheme. The protocol can be anything except http and javascript. 679 * 680 * @since 6.3.2 681 * 682 * @param string $url - The redirect URL to be validated. 683 * 684 * @return true|WP_Error True if the redirect URL is valid, a WP_Error object otherwise. 685 */ 686 function wp_is_authorize_application_redirect_url_valid( $url ) { 687 $bad_protocols = array( 'javascript', 'data' ); 688 if ( empty( $url ) ) { 689 return true; 690 } 691 692 // Based on https://www.rfc-editor.org/rfc/rfc2396#section-3.1 693 $valid_scheme_regex = '/^[a-zA-Z][a-zA-Z0-9+.-]*:/'; 694 if ( ! preg_match( $valid_scheme_regex, $url ) ) { 695 return new WP_Error( 696 'invalid_redirect_url_format', 697 __( 'Invalid URL format.' ) 698 ); 699 } 700 701 /** 702 * Filters the list of invalid protocols used in applications redirect URLs. 703 * 704 * @since 6.3.2 705 * 706 * @param string[] $bad_protocols Array of invalid protocols. 707 * @param string $url The redirect URL to be validated. 708 */ 709 $invalid_protocols = array_map( 'strtolower', apply_filters( 'wp_authorize_application_redirect_url_invalid_protocols', $bad_protocols, $url ) ); 710 711 $scheme = wp_parse_url( $url, PHP_URL_SCHEME ); 712 $host = wp_parse_url( $url, PHP_URL_HOST ); 713 $is_local = 'local' === wp_get_environment_type(); 714 715 // validates if the proper URI format is applied to the $url 716 if ( empty( $host ) || empty( $scheme ) || in_array( strtolower( $scheme ), $invalid_protocols, true ) ) { 717 return new WP_Error( 718 'invalid_redirect_url_format', 719 __( 'Invalid URL format.' ) 720 ); 721 } 722 723 if ( 'http' === $scheme && ! $is_local ) { 724 return new WP_Error( 725 'invalid_redirect_scheme', 726 __( 'The URL must be served over a secure connection.' ) 727 ); 728 } 729 730 return true; 731 } -
branches/6.2/src/wp-includes/Requests/src/Hooks.php
r54997 r56895 97 97 return true; 98 98 } 99 100 public function __wakeup() { 101 throw new \LogicException( __CLASS__ . ' should never be unserialized' ); 102 } 99 103 } -
branches/6.2/src/wp-includes/Requests/src/Iri.php
r54997 r56895 718 718 } 719 719 720 public function __wakeup() { 721 $class_props = get_class_vars( __CLASS__ ); 722 $string_props = array( 'scheme', 'iuserinfo', 'ihost', 'port', 'ipath', 'iquery', 'ifragment' ); 723 $array_props = array( 'normalization' ); 724 foreach ( $class_props as $prop => $default_value ) { 725 if ( in_array( $prop, $string_props, true ) && ! is_string( $this->$prop ) ) { 726 throw new UnexpectedValueException(); 727 } elseif ( in_array( $prop, $array_props, true ) && ! is_array( $this->$prop ) ) { 728 throw new UnexpectedValueException(); 729 } 730 $this->$prop = null; 731 } 732 } 733 720 734 /** 721 735 * Set the entire IRI. Returns true on success, false on failure (if there -
branches/6.2/src/wp-includes/Requests/src/Session.php
r54997 r56895 266 266 } 267 267 268 public function __wakeup() { 269 throw new \LogicException( __CLASS__ . ' should never be unserialized' ); 270 } 271 268 272 /** 269 273 * Merge a request's data with the default data -
branches/6.2/src/wp-includes/class-wp-block-patterns-registry.php
r55174 r56895 198 198 } 199 199 200 public function __wakeup() { 201 if ( ! $this->registered_patterns ) { 202 return; 203 } 204 if ( ! is_array( $this->registered_patterns ) ) { 205 throw new UnexpectedValueException(); 206 } 207 foreach ( $this->registered_patterns as $value ) { 208 if ( ! is_array( $value ) ) { 209 throw new UnexpectedValueException(); 210 } 211 } 212 $this->registered_patterns_outside_init = array(); 213 } 214 200 215 /** 201 216 * Utility method to retrieve the main instance of the class. -
branches/6.2/src/wp-includes/class-wp-block-type-registry.php
r54133 r56895 169 169 } 170 170 171 public function __wakeup() { 172 if ( ! $this->registered_block_types ) { 173 return; 174 } 175 if ( ! is_array( $this->registered_block_types ) ) { 176 throw new UnexpectedValueException(); 177 } 178 foreach ( $this->registered_block_types as $value ) { 179 if ( ! $value instanceof WP_Block_Type ) { 180 throw new UnexpectedValueException(); 181 } 182 } 183 } 184 171 185 /** 172 186 * Utility method to retrieve the main instance of the class. -
branches/6.2/src/wp-includes/class-wp-theme.php
r55426 r56895 741 741 742 742 /** 743 * Perform reinitialization tasks. 744 * 745 * Prevents a callback from being injected during unserialization of an object. 746 * 747 * @return void 748 */ 749 public function __wakeup() { 750 if ( $this->parent && ! $this->parent instanceof self ) { 751 throw new UnexpectedValueException(); 752 } 753 if ( $this->headers && ! is_array( $this->headers ) ) { 754 throw new UnexpectedValueException(); 755 } 756 foreach ( $this->headers as $value ) { 757 if ( ! is_string( $value ) ) { 758 throw new UnexpectedValueException(); 759 } 760 } 761 $this->headers_sanitized = array(); 762 } 763 764 /** 743 765 * Adds theme data to cache. 744 766 * … … 1809 1831 return strnatcasecmp( $a->name_translated, $b->name_translated ); 1810 1832 } 1833 1834 private static function _check_headers_property_has_correct_type( $headers ) { 1835 if ( ! is_array( $headers ) ) { 1836 return false; 1837 } 1838 foreach ( $headers as $key => $value ) { 1839 if ( ! is_string( $key ) || ! is_string( $value ) ) { 1840 return false; 1841 } 1842 } 1843 return true; 1844 } 1811 1845 } -
branches/6.2/src/wp-includes/media.php
r55769 r56895 2460 2460 } 2461 2461 } elseif ( ! empty( $atts['exclude'] ) ) { 2462 $post_parent_id = $id; 2462 2463 $attachments = get_children( 2463 2464 array( … … 2472 2473 ); 2473 2474 } else { 2475 $post_parent_id = $id; 2474 2476 $attachments = get_children( 2475 2477 array( … … 2482 2484 ) 2483 2485 ); 2486 } 2487 2488 if ( ! empty( $post_parent_id ) ) { 2489 $post_parent = get_post( $post_parent_id ); 2490 2491 // terminate the shortcode execution if user cannot read the post or password-protected 2492 if ( 2493 ( ! is_post_publicly_viewable( $post_parent->ID ) && ! current_user_can( 'read_post', $post_parent->ID ) ) 2494 || post_password_required( $post_parent ) ) { 2495 return ''; 2496 } 2484 2497 } 2485 2498 … … 2816 2829 } 2817 2830 2831 if ( ! empty( $args['post_parent'] ) ) { 2832 $post_parent = get_post( $id ); 2833 2834 // terminate the shortcode execution if user cannot read the post or password-protected 2835 if ( ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) { 2836 return ''; 2837 } 2838 } 2839 2818 2840 if ( empty( $attachments ) ) { 2819 2841 return ''; -
branches/6.2/src/wp-includes/rest-api.php
r55293 r56895 1069 1069 1070 1070 if ( ! $result ) { 1071 add_filter( 'rest_send_nocache_headers', '__return_true', 20 ); 1071 1072 return new WP_Error( 'rest_cookie_invalid_nonce', __( 'Cookie check failed' ), array( 'status' => 403 ) ); 1072 1073 } -
branches/6.2/src/wp-includes/rest-api/class-wp-rest-server.php
r55361 r56895 360 360 361 361 /** 362 * Filters whether to send nocache headers on a REST API request.363 *364 * @since 4.4.0365 *366 * @param bool $rest_send_nocache_headers Whether to send no-cache headers.367 */368 $send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() );369 if ( $send_no_cache_headers ) {370 foreach ( wp_get_nocache_headers() as $header => $header_value ) {371 if ( empty( $header_value ) ) {372 $this->remove_header( $header );373 } else {374 $this->send_header( $header, $header_value );375 }376 }377 }378 379 /**380 362 * Filters whether the REST API is enabled. 381 363 * … … 431 413 * header. 432 414 */ 415 $method_overridden = false; 433 416 if ( isset( $_GET['_method'] ) ) { 434 417 $request->set_method( $_GET['_method'] ); 435 418 } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { 436 419 $request->set_method( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ); 420 $method_overridden = true; 437 421 } 438 422 … … 493 477 */ 494 478 $served = apply_filters( 'rest_pre_serve_request', false, $result, $request, $this ); 479 480 /** 481 * Filters whether to send nocache headers on a REST API request. 482 * 483 * @since 4.4.0 484 * @since 6.x.x Moved the block to catch the filter added on rest_cookie_check_errors() from rest-api.php 485 * 486 * @param bool $rest_send_nocache_headers Whether to send no-cache headers. 487 */ 488 $send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() ); 489 490 // send no cache headers if the $send_no_cache_headers is true 491 // OR if the HTTP_X_HTTP_METHOD_OVERRIDE is used but resulted a 4xx response code. 492 if ( $send_no_cache_headers || ( true === $method_overridden && strpos( $code, '4' ) === 0 ) ) { 493 foreach ( wp_get_nocache_headers() as $header => $header_value ) { 494 if ( empty( $header_value ) ) { 495 $this->remove_header( $header ); 496 } else { 497 $this->send_header( $header, $header_value ); 498 } 499 } 500 } 495 501 496 502 if ( ! $served ) { -
branches/6.2/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
r55325 r56895 319 319 320 320 if ( ! empty( $prepared_args['search'] ) ) { 321 if ( ! current_user_can( 'list_users' ) ) { 322 $prepared_args['search_columns'] = array( 'ID', 'user_login', 'user_nicename', 'display_name' ); 323 } 321 324 $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; 322 325 } -
branches/6.2/src/wp-includes/shortcodes.php
r55119 r56895 167 167 } 168 168 return false; 169 } 170 171 /** 172 * Returns a list of registered shortcode names found in the given content. 173 * 174 * Example usage: 175 * 176 * get_shortcode_tags_in_content( '[audio src="file.mp3"][/audio] [foo] [gallery ids="1,2,3"]' ); 177 * // array( 'audio', 'gallery' ) 178 * 179 * @since 6.3.2 180 * 181 * @param string $content The content to check. 182 * @return string[] An array of registered shortcode names found in the content. 183 */ 184 function get_shortcode_tags_in_content( $content ) { 185 if ( false === strpos( $content, '[' ) ) { 186 return array(); 187 } 188 189 preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER ); 190 if ( empty( $matches ) ) { 191 return array(); 192 } 193 194 $tags = array(); 195 foreach ( $matches as $shortcode ) { 196 $tags[] = $shortcode[2]; 197 198 if ( ! empty( $shortcode[5] ) ) { 199 $deep_tags = get_shortcode_tags_in_content( $shortcode[5] ); 200 if ( ! empty( $deep_tags ) ) { 201 $tags = array_merge( $tags, $deep_tags ); 202 } 203 } 204 } 205 206 return $tags; 169 207 } 170 208
Note: See TracChangeset
for help on using the changeset viewer.