diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index 951309523286c..b50ebc8c76678 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -2296,6 +2296,10 @@ function _post_states( $post, $display = true ) { */ function get_post_states( $post ) { $post_states = array(); + if ( ! $post instanceof WP_Post ) { + return $post_states; + } + $post_status = $_REQUEST['post_status'] ?? ''; if ( ! empty( $post->post_password ) ) { diff --git a/src/wp-includes/nav-menu.php b/src/wp-includes/nav-menu.php index 83a67cfe2a800..dc6de5c70c662 100644 --- a/src/wp-includes/nav-menu.php +++ b/src/wp-includes/nav-menu.php @@ -875,10 +875,12 @@ function wp_setup_nav_menu_item( $menu_item ) { $menu_item->type_label = $object->labels->singular_name; // Denote post states for special pages (only in the admin). if ( function_exists( 'get_post_states' ) ) { - $menu_post = get_post( $menu_item->object_id ); - $post_states = get_post_states( $menu_post ); - if ( $post_states ) { - $menu_item->type_label = wp_strip_all_tags( implode( ', ', $post_states ) ); + $menu_post = get_post( $menu_item->object_id ); + if ( $menu_post instanceof WP_Post ) { + $post_states = get_post_states( $menu_post ); + if ( $post_states ) { + $menu_item->type_label = wp_strip_all_tags( implode( ', ', $post_states ) ); + } } } } else { diff --git a/tests/phpunit/tests/admin/includesTemplate.php b/tests/phpunit/tests/admin/includesTemplate.php index 909aff217a583..15a5edd672f09 100644 --- a/tests/phpunit/tests/admin/includesTemplate.php +++ b/tests/phpunit/tests/admin/includesTemplate.php @@ -494,4 +494,20 @@ public function test_wp_add_dashboard_widget() { // This doesn't actually get removed due to the invalid priority. remove_meta_box( 'dashboard2', 'dashboard', 'normal' ); } + + /** + * Tests that get_post_states() handles a null value gracefully. + * + * This can happen when get_post() returns null (e.g., when a post + * doesn't exist) and that result is passed to get_post_states() + * without being checked first. + * + * @ticket 58932 + * + * @covers ::get_post_states + */ + public function test_get_post_states_with_null_returns_empty_array() { + $result = get_post_states( null ); + $this->assertSame( array(), $result, 'get_post_states() should return an empty array when WP_Post is not supplied.' ); + } }