diff --git a/src/wp-admin/edit-comments.php b/src/wp-admin/edit-comments.php index 46cf66d393985..2229f78182021 100644 --- a/src/wp-admin/edit-comments.php +++ b/src/wp-admin/edit-comments.php @@ -275,7 +275,7 @@ } } -if ( isset( $_REQUEST['s'] ) && strlen( $_REQUEST['s'] ) ) { +if ( isset( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) && strlen( $_REQUEST['s'] ) ) { echo ''; printf( /* translators: %s: Search query. */ diff --git a/src/wp-admin/edit-tags.php b/src/wp-admin/edit-tags.php index 6efdeb9b0527d..1edf7d351c77e 100644 --- a/src/wp-admin/edit-tags.php +++ b/src/wp-admin/edit-tags.php @@ -336,7 +336,7 @@

'; printf( /* translators: %s: Search query. */ diff --git a/src/wp-admin/edit.php b/src/wp-admin/edit.php index 15cb17d303bd3..6ab063e804cc2 100644 --- a/src/wp-admin/edit.php +++ b/src/wp-admin/edit.php @@ -89,7 +89,9 @@ if ( 'delete_all' === $doaction ) { // Prepare for deletion of all posts with a specified post status (i.e. Empty Trash). - $post_status = preg_replace( '/[^a-z0-9_-]+/i', '', $_REQUEST['post_status'] ); + $post_status = isset( $_REQUEST['post_status'] ) && is_string( $_REQUEST['post_status'] ) + ? preg_replace( '/[^a-z0-9_-]+/i', '', $_REQUEST['post_status'] ) + : ''; // Validate the post status exists. if ( get_post_status_object( $post_status ) ) { /** @@ -102,10 +104,15 @@ $doaction = 'delete'; } elseif ( isset( $_REQUEST['media'] ) ) { $post_ids = $_REQUEST['media']; - } elseif ( isset( $_REQUEST['ids'] ) ) { + } elseif ( isset( $_REQUEST['ids'] ) && is_string( $_REQUEST['ids'] ) ) { $post_ids = explode( ',', $_REQUEST['ids'] ); } elseif ( ! empty( $_REQUEST['post'] ) ) { - $post_ids = array_map( 'intval', $_REQUEST['post'] ); + $post_ids = array_map( + static function ( $post_id ): int { + return is_numeric( $post_id ) ? (int) $post_id : 0; + }, + (array) $_REQUEST['post'] + ); } if ( empty( $post_ids ) ) { @@ -422,7 +429,7 @@ echo ' ' . esc_html( $post_type_object->labels->add_new_item ) . ''; } -if ( isset( $_REQUEST['s'] ) && strlen( $_REQUEST['s'] ) ) { +if ( isset( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) && strlen( $_REQUEST['s'] ) ) { echo ''; printf( /* translators: %s: Search query. */ @@ -489,10 +496,10 @@ search_box( $post_type_object->labels->search_items, 'post' ); ?> - + - + diff --git a/src/wp-admin/includes/class-wp-comments-list-table.php b/src/wp-admin/includes/class-wp-comments-list-table.php index 1dff5d26755ce..824d4585631e7 100644 --- a/src/wp-admin/includes/class-wp-comments-list-table.php +++ b/src/wp-admin/includes/class-wp-comments-list-table.php @@ -107,7 +107,7 @@ public function prepare_items() { $comment_type = ''; - if ( ! empty( $_REQUEST['comment_type'] ) && ! in_array( $_REQUEST['comment_type'], array( 'note', 'reaction' ), true ) ) { + if ( ! empty( $_REQUEST['comment_type'] ) && is_string( $_REQUEST['comment_type'] ) && ! in_array( $_REQUEST['comment_type'], array( 'note', 'reaction' ), true ) ) { $comment_type = $_REQUEST['comment_type']; } @@ -132,14 +132,14 @@ public function prepare_items() { $page = $this->get_pagenum(); - if ( isset( $_REQUEST['start'] ) ) { - $start = $_REQUEST['start']; + if ( isset( $_REQUEST['start'] ) && is_numeric( $_REQUEST['start'] ) ) { + $start = (int) $_REQUEST['start']; } else { $start = ( $page - 1 ) * $comments_per_page; } - if ( $doing_ajax && isset( $_REQUEST['offset'] ) ) { - $start += $_REQUEST['offset']; + if ( $doing_ajax && isset( $_REQUEST['offset'] ) && is_numeric( $_REQUEST['offset'] ) ) { + $start += (int) $_REQUEST['offset']; } $status_map = array( diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php index 08b31d5eb7ba0..b90e911d058f2 100644 --- a/src/wp-admin/includes/class-wp-list-table.php +++ b/src/wp-admin/includes/class-wp-list-table.php @@ -415,19 +415,22 @@ public function search_box( $text, $input_id ) { if ( ! empty( $_REQUEST['orderby'] ) ) { if ( is_array( $_REQUEST['orderby'] ) ) { foreach ( $_REQUEST['orderby'] as $key => $value ) { + if ( ! is_string( $value ) ) { + continue; + } echo ''; } } else { echo ''; } } - if ( ! empty( $_REQUEST['order'] ) ) { + if ( ! empty( $_REQUEST['order'] ) && is_string( $_REQUEST['order'] ) ) { echo ''; } - if ( ! empty( $_REQUEST['post_mime_type'] ) ) { + if ( ! empty( $_REQUEST['post_mime_type'] ) && is_string( $_REQUEST['post_mime_type'] ) ) { echo ''; } - if ( ! empty( $_REQUEST['detached'] ) ) { + if ( ! empty( $_REQUEST['detached'] ) && is_string( $_REQUEST['detached'] ) ) { echo ''; } ?> diff --git a/src/wp-admin/includes/class-wp-media-list-table.php b/src/wp-admin/includes/class-wp-media-list-table.php index feac4753d3e92..7e8eeee48ec59 100644 --- a/src/wp-admin/includes/class-wp-media-list-table.php +++ b/src/wp-admin/includes/class-wp-media-list-table.php @@ -88,7 +88,10 @@ public function ajax_user_can() { public function prepare_items() { global $mode, $wp_query, $post_mime_types, $avail_post_mime_types; - $mode = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode']; + $mode = 'list'; + if ( ! empty( $_REQUEST['mode'] ) && is_string( $_REQUEST['mode'] ) ) { + $mode = $_REQUEST['mode']; + } /* * Exclude attachments scheduled for deletion in the next two hours @@ -150,7 +153,10 @@ protected function get_views() { $type_links = array(); - $filter = empty( $_GET['attachment-filter'] ) ? '' : $_GET['attachment-filter']; + $filter = ''; + if ( ! empty( $_GET['attachment-filter'] ) && is_string( $_GET['attachment-filter'] ) ) { + $filter = $_GET['attachment-filter']; + } $type_links['all'] = sprintf( '', diff --git a/src/wp-admin/includes/class-wp-plugin-install-list-table.php b/src/wp-admin/includes/class-wp-plugin-install-list-table.php index 3f6d2a104d099..f4636dd2bac17 100644 --- a/src/wp-admin/includes/class-wp-plugin-install-list-table.php +++ b/src/wp-admin/includes/class-wp-plugin-install-list-table.php @@ -203,8 +203,8 @@ public function prepare_items() { switch ( $tab ) { case 'search': - $type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; - $term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : ''; + $type = isset( $_REQUEST['type'] ) && is_string( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; + $term = isset( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : ''; switch ( $type ) { case 'tag': diff --git a/src/wp-admin/includes/class-wp-plugins-list-table.php b/src/wp-admin/includes/class-wp-plugins-list-table.php index 7778f21b4688b..39036d56f8858 100644 --- a/src/wp-admin/includes/class-wp-plugins-list-table.php +++ b/src/wp-admin/includes/class-wp-plugins-list-table.php @@ -62,7 +62,7 @@ public function __construct( $args = array() ) { $status = sanitize_key( $_REQUEST['plugin_status'] ); } - if ( isset( $_REQUEST['s'] ) ) { + if ( isset( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) ) { $_SERVER['REQUEST_URI'] = add_query_arg( 's', wp_unslash( $_REQUEST['s'] ) ); } @@ -449,7 +449,7 @@ public function _order_callback( $plugin_a, $plugin_b ) { public function no_items() { global $plugins; - if ( ! empty( $_REQUEST['s'] ) ) { + if ( ! empty( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) ) { $s = esc_html( urldecode( wp_unslash( $_REQUEST['s'] ) ) ); /* translators: %s: Plugin search term. */ @@ -481,10 +481,10 @@ public function search_box( $text, $input_id ) { $input_id = $input_id . '-search-input'; - if ( ! empty( $_REQUEST['orderby'] ) ) { + if ( ! empty( $_REQUEST['orderby'] ) && is_string( $_REQUEST['orderby'] ) ) { echo ''; } - if ( ! empty( $_REQUEST['order'] ) ) { + if ( ! empty( $_REQUEST['order'] ) && is_string( $_REQUEST['order'] ) ) { echo ''; } ?> diff --git a/src/wp-admin/includes/class-wp-terms-list-table.php b/src/wp-admin/includes/class-wp-terms-list-table.php index 9481f0967a744..be70ed1c9b4de 100644 --- a/src/wp-admin/includes/class-wp-terms-list-table.php +++ b/src/wp-admin/includes/class-wp-terms-list-table.php @@ -109,7 +109,7 @@ public function prepare_items() { $tags_per_page = apply_filters( 'edit_categories_per_page', $tags_per_page ); } - $search = ! empty( $_REQUEST['s'] ) ? trim( wp_unslash( $_REQUEST['s'] ) ) : ''; + $search = ! empty( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) ? trim( wp_unslash( $_REQUEST['s'] ) ) : ''; $args = array( 'taxonomy' => $taxonomy, @@ -119,11 +119,11 @@ public function prepare_items() { 'hide_empty' => 0, ); - if ( ! empty( $_REQUEST['orderby'] ) ) { + if ( ! empty( $_REQUEST['orderby'] ) && is_string( $_REQUEST['orderby'] ) ) { $args['orderby'] = trim( wp_unslash( $_REQUEST['orderby'] ) ); } - if ( ! empty( $_REQUEST['order'] ) ) { + if ( ! empty( $_REQUEST['order'] ) && is_string( $_REQUEST['order'] ) ) { $args['order'] = trim( wp_unslash( $_REQUEST['order'] ) ); } diff --git a/src/wp-admin/includes/class-wp-users-list-table.php b/src/wp-admin/includes/class-wp-users-list-table.php index 46eac2064660e..856dee311c91f 100644 --- a/src/wp-admin/includes/class-wp-users-list-table.php +++ b/src/wp-admin/includes/class-wp-users-list-table.php @@ -83,9 +83,9 @@ public function ajax_user_can() { public function prepare_items() { global $role, $usersearch; - $usersearch = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : ''; + $usersearch = isset( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : ''; - $role = $_REQUEST['role'] ?? ''; + $role = isset( $_REQUEST['role'] ) && is_string( $_REQUEST['role'] ) ? $_REQUEST['role'] : ''; $per_page = ( $this->is_site_users ) ? 'site_users_network_per_page' : 'users_per_page'; $users_per_page = $this->get_items_per_page( $per_page ); @@ -118,11 +118,11 @@ public function prepare_items() { $args['blog_id'] = $this->site_id; } - if ( isset( $_REQUEST['orderby'] ) ) { + if ( isset( $_REQUEST['orderby'] ) && is_string( $_REQUEST['orderby'] ) ) { $args['orderby'] = $_REQUEST['orderby']; } - if ( isset( $_REQUEST['order'] ) ) { + if ( isset( $_REQUEST['order'] ) && is_string( $_REQUEST['order'] ) ) { $args['order'] = $_REQUEST['order']; } diff --git a/src/wp-admin/includes/plugin-install.php b/src/wp-admin/includes/plugin-install.php index 496b7ffd36679..7484eb9e8ca8e 100644 --- a/src/wp-admin/includes/plugin-install.php +++ b/src/wp-admin/includes/plugin-install.php @@ -313,8 +313,8 @@ function install_dashboard() { * @phpstan-param true $deprecated */ function install_search_form( $deprecated = true ) { - $type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; - $term = isset( $_REQUEST['s'] ) ? urldecode( wp_unslash( $_REQUEST['s'] ) ) : ''; + $type = isset( $_REQUEST['type'] ) && is_string( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; + $term = isset( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) ? urldecode( wp_unslash( $_REQUEST['s'] ) ) : ''; ?>
diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index c4496dea3d403..f552117d2b9c0 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -2108,7 +2108,7 @@ function _draft_or_post_title( $post = 0 ) { * @since 2.7.0 */ function _admin_search_query() { - echo isset( $_REQUEST['s'] ) ? esc_attr( wp_unslash( $_REQUEST['s'] ) ) : ''; + echo isset( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) ? esc_attr( wp_unslash( $_REQUEST['s'] ) ) : ''; } /** diff --git a/src/wp-admin/plugins.php b/src/wp-admin/plugins.php index 62e904accaac2..3134e8c61f5d5 100644 --- a/src/wp-admin/plugins.php +++ b/src/wp-admin/plugins.php @@ -27,7 +27,7 @@ $action = $wp_list_table->current_action(); $plugin = isset( $_REQUEST['plugin'] ) ? wp_unslash( $_REQUEST['plugin'] ) : ''; -$s = isset( $_REQUEST['s'] ) ? urlencode( wp_unslash( $_REQUEST['s'] ) ) : ''; +$s = isset( $_REQUEST['s'] ) && is_string( $_REQUEST['s'] ) ? urlencode( wp_unslash( $_REQUEST['s'] ) ) : ''; // Clean up request URI from temporary args for screen options/paging uri's to work as expected. $query_args_to_remove = array( diff --git a/src/wp-admin/site-health.php b/src/wp-admin/site-health.php index 1a70e2e1dd8f1..d09c9ed412b5f 100644 --- a/src/wp-admin/site-health.php +++ b/src/wp-admin/site-health.php @@ -36,7 +36,7 @@ 'tab-count-' . count( $tabs ), ); -$current_tab = $_GET['tab'] ?? ''; +$current_tab = isset( $_GET['tab'] ) && is_string( $_GET['tab'] ) ? $_GET['tab'] : ''; $title = sprintf( // translators: %s: The currently displayed tab. @@ -206,7 +206,7 @@
'; printf( /* translators: %s: Search query. */ diff --git a/src/wp-admin/users.php b/src/wp-admin/users.php index 36689221565f6..d4357c951a15c 100644 --- a/src/wp-admin/users.php +++ b/src/wp-admin/users.php @@ -879,7 +879,7 @@ search_box( __( 'Search Users' ), 'user' ); ?> - + diff --git a/src/wp-includes/class-wp-comment-query.php b/src/wp-includes/class-wp-comment-query.php index ad706ba532114..bc82e41a77841 100644 --- a/src/wp-includes/class-wp-comment-query.php +++ b/src/wp-includes/class-wp-comment-query.php @@ -843,7 +843,11 @@ protected function get_comment_ids() { } // Falsey search strings are ignored. - if ( isset( $this->query_vars['search'] ) && strlen( $this->query_vars['search'] ) ) { + if ( + isset( $this->query_vars['search'] ) && + is_scalar( $this->query_vars['search'] ) && + strlen( $this->query_vars['search'] ) + ) { $search_sql = $this->get_search_sql( $this->query_vars['search'], array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' ) diff --git a/src/wp-includes/class-wp-user-query.php b/src/wp-includes/class-wp-user-query.php index 61fc3edbc8ef9..7325236116ba6 100644 --- a/src/wp-includes/class-wp-user-query.php +++ b/src/wp-includes/class-wp-user-query.php @@ -993,6 +993,10 @@ public function get_total() { protected function parse_orderby( $orderby ) { global $wpdb; + if ( ! is_string( $orderby ) ) { + return ''; + } + $meta_query_clauses = $this->meta_query->get_clauses(); $_orderby = ''; diff --git a/tests/phpunit/tests/comment/query.php b/tests/phpunit/tests/comment/query.php index 77f60a6f4c124..78e8399c87628 100644 --- a/tests/phpunit/tests/comment/query.php +++ b/tests/phpunit/tests/comment/query.php @@ -2637,6 +2637,21 @@ public function test_search_null_should_be_ignored() { $this->assertStringNotContainsString( 'comment_author LIKE', $q->request ); } + /** + * @ticket 66432 + * + * @covers WP_Comment_Query::query + */ + public function test_search_array_should_be_ignored() { + $q = new WP_Comment_Query(); + $q->query( + array( + 'search' => array( 'foo' ), + ) + ); + $this->assertStringNotContainsString( 'comment_author LIKE', $q->request ); + } + /** * @ticket 35513 * diff --git a/tests/phpunit/tests/user/query.php b/tests/phpunit/tests/user/query.php index ee73f1a2cb943..77f4f1955cd08 100644 --- a/tests/phpunit/tests/user/query.php +++ b/tests/phpunit/tests/user/query.php @@ -223,6 +223,74 @@ public function test_orderby_meta_value() { $this->assertSame( $expected, $q->get_results() ); } + /** + * Tests that a non-string 'orderby' entry is skipped rather than causing a fatal error. + * + * @ticket 66432 + */ + public function test_orderby_should_skip_non_string_entries() { + $user_ids = $this->create_users_with_reversed_display_names(); + + $q = new WP_User_Query( + array( + 'include' => $user_ids, + 'orderby' => array( array( 'login' ), 'display_name' ), + 'order' => 'ASC', + 'fields' => 'ID', + ) + ); + + $this->assertSame( array_map( 'strval', array_reverse( $user_ids ) ), $q->get_results() ); + } + + /** + * Tests that 'orderby' falls back to the user login when no entry is a string. + * + * @ticket 66432 + */ + public function test_orderby_should_fall_back_to_user_login_when_no_entry_is_a_string() { + $user_ids = $this->create_users_with_reversed_display_names(); + + $q = new WP_User_Query( + array( + 'include' => $user_ids, + 'orderby' => array( array( 'display_name' ) ), + 'order' => 'ASC', + 'fields' => 'ID', + ) + ); + + $this->assertSame( array_map( 'strval', $user_ids ), $q->get_results() ); + } + + /** + * Creates users whose display names sort in the reverse order of their logins. + * + * @return int[] User IDs, in ascending order of user login. + */ + private function create_users_with_reversed_display_names(): array { + return array( + self::factory()->user->create( + array( + 'user_login' => 'orderby_a', + 'display_name' => 'Zed', + ) + ), + self::factory()->user->create( + array( + 'user_login' => 'orderby_b', + 'display_name' => 'Yan', + ) + ), + self::factory()->user->create( + array( + 'user_login' => 'orderby_c', + 'display_name' => 'Xia', + ) + ), + ); + } + /** * @ticket 27887 */