Commit 1e68f9f454 for wordpress.org

commit 1e68f9f4542d31ee968bcf0582e8f59a271e1e88
Author: peterwilsoncc <peterwilsoncc@git.wordpress.org>
Date:   Fri Oct 30 05:05:00 2026 +0000

    Sitemaps: Ensure only supported subtypes return a sitemap.

    Updates `WP_Sitemaps::render_sitemaps()` to throw a 404 File Not Found error for sub-type requests that do not match a registered sub-type.

    Introduces tests to ensure:

    * sitemaps for a registered private post type trigger a 404
    * sitemaps for a registered public post type trigger a 200 for in range pages
    * sitemaps for a registered private taxonomy trigger a 404
    * sitemaps for a registered public taxonomy trigger a 200 for in range pages

    In order that these tests are able to run, `WP_Sitemaps::render_sitemaps()` is modified to avoid exiting when `WP_RUN_CORE_TESTS` is defined and `true`.

    Developed in https://github.com/WordPress/wordpress-develop/pull/15012.

    Follow up to r64792.

    Props westonruter, jasonbahl.
    Fixes #61293.



    Built from https://develop.svn.wordpress.org/trunk@65043


    git-svn-id: http://core.svn.wordpress.org/trunk@64193 1a063a9b-81f0-0310-95a4-ce76da25c4cd

diff --git a/wp-includes/sitemaps/class-wp-sitemaps-provider.php b/wp-includes/sitemaps/class-wp-sitemaps-provider.php
index 13a03f99a4..653c6c4d1b 100644
--- a/wp-includes/sitemaps/class-wp-sitemaps-provider.php
+++ b/wp-includes/sitemaps/class-wp-sitemaps-provider.php
@@ -174,7 +174,7 @@ abstract class WP_Sitemaps_Provider {
 	 *
 	 * @since 5.5.0
 	 *
-	 * @return array List of object subtypes objects keyed by their name.
+	 * @return array<string, object> List of object subtypes objects keyed by their name.
 	 */
 	public function get_object_subtypes() {
 		return array();
diff --git a/wp-includes/sitemaps/class-wp-sitemaps-renderer.php b/wp-includes/sitemaps/class-wp-sitemaps-renderer.php
index 8b15b04031..e852fef0ab 100644
--- a/wp-includes/sitemaps/class-wp-sitemaps-renderer.php
+++ b/wp-includes/sitemaps/class-wp-sitemaps-renderer.php
@@ -106,7 +106,9 @@ class WP_Sitemaps_Renderer {
 	 * @param array $sitemaps Array of sitemap URLs.
 	 */
 	public function render_index( $sitemaps ) {
-		header( 'Content-Type: application/xml; charset=UTF-8' );
+		if ( ! headers_sent() ) {
+			header( 'Content-Type: application/xml; charset=UTF-8' );
+		}

 		$this->check_for_simple_xml_availability();

@@ -171,7 +173,9 @@ class WP_Sitemaps_Renderer {
 	 * @param array $url_list Array of URLs for a sitemap.
 	 */
 	public function render_sitemap( $url_list ) {
-		header( 'Content-Type: application/xml; charset=UTF-8' );
+		if ( ! headers_sent() ) {
+			header( 'Content-Type: application/xml; charset=UTF-8' );
+		}

 		$this->check_for_simple_xml_availability();

diff --git a/wp-includes/sitemaps/class-wp-sitemaps.php b/wp-includes/sitemaps/class-wp-sitemaps.php
index 142cd69d8b..92c3375912 100644
--- a/wp-includes/sitemaps/class-wp-sitemaps.php
+++ b/wp-includes/sitemaps/class-wp-sitemaps.php
@@ -202,6 +202,12 @@ class WP_Sitemaps {
 			$paged = 1;
 		}

+		// Force a 404 and bail early if the sub-type query variable is set to an invalid value.
+		if ( $object_subtype && ! array_key_exists( $object_subtype, $provider->get_object_subtypes() ) ) {
+			$this->send_404();
+			return;
+		}
+
 		$url_list = $provider->get_url_list( $paged, $object_subtype );

 		// Force a 404 and bail early if the requested page is out of range.
@@ -211,7 +217,9 @@ class WP_Sitemaps {
 		}

 		$this->renderer->render_sitemap( $url_list );
-		exit;
+		if ( ! defined( 'WP_RUN_CORE_TESTS' ) || ! WP_RUN_CORE_TESTS ) {
+			exit;
+		}
 	}

 	/**
diff --git a/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php b/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php
index 95bd10c5e4..c96b12c7e2 100644
--- a/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php
+++ b/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php
@@ -31,7 +31,7 @@ class WP_Sitemaps_Posts extends WP_Sitemaps_Provider {
 	 *
 	 * @since 5.5.0
 	 *
-	 * @return WP_Post_Type[] Array of registered post type objects keyed by their name.
+	 * @return array<string, WP_Post_Type> Array of registered post type objects keyed by their name.
 	 */
 	public function get_object_subtypes() {
 		$post_types = get_post_types( array( 'public' => true ), 'objects' );
@@ -44,7 +44,7 @@ class WP_Sitemaps_Posts extends WP_Sitemaps_Provider {
 		 *
 		 * @since 5.5.0
 		 *
-		 * @param WP_Post_Type[] $post_types Array of registered post type objects keyed by their name.
+		 * @param array<string, WP_Post_Type> $post_types Array of registered post type objects keyed by their name.
 		 */
 		return apply_filters( 'wp_sitemaps_post_types', $post_types );
 	}
diff --git a/wp-includes/sitemaps/providers/class-wp-sitemaps-taxonomies.php b/wp-includes/sitemaps/providers/class-wp-sitemaps-taxonomies.php
index 0c53e95a42..b912fa4c54 100644
--- a/wp-includes/sitemaps/providers/class-wp-sitemaps-taxonomies.php
+++ b/wp-includes/sitemaps/providers/class-wp-sitemaps-taxonomies.php
@@ -30,7 +30,7 @@ class WP_Sitemaps_Taxonomies extends WP_Sitemaps_Provider {
 	 *
 	 * @since 5.5.0
 	 *
-	 * @return WP_Taxonomy[] Array of registered taxonomy objects keyed by their name.
+	 * @return array<string, WP_Taxonomy> Array of registered taxonomy objects keyed by their name.
 	 */
 	public function get_object_subtypes() {
 		$taxonomies = get_taxonomies( array( 'public' => true ), 'objects' );
@@ -42,7 +42,7 @@ class WP_Sitemaps_Taxonomies extends WP_Sitemaps_Provider {
 		 *
 		 * @since 5.5.0
 		 *
-		 * @param WP_Taxonomy[] $taxonomies Array of registered taxonomy objects keyed by their name.
+		 * @param array<string, WP_Taxonomy> $taxonomies Array of registered taxonomy objects keyed by their name.
 		 */
 		return apply_filters( 'wp_sitemaps_taxonomies', $taxonomies );
 	}
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 60be0ee02d..ec98be8014 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.2-beta3-65042';
+$wp_version = '7.2-beta3-65043';

 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.