Commit 9687d2ad37 for wordpress.org

commit 9687d2ad3779c882d5d910d723bf9ff1b3a17f72
Author: westonruter <westonruter@git.wordpress.org>
Date:   Thu Nov 5 17:28:55 2026 +0000

    Code Quality: Fix the `nullCoalesce.property` PHPStan error.

    Since `WP_Query::$max_num_pages` is never `null`, the `?? 1` fallback in `paginate_links()` never applied, so the property is now read directly.

    The property is also documented as a non-negative integer. This exposed that `WP_Query::set_found_posts()` could compute a negative page count when a `found_posts` filter returns a negative number, or when a filter injects a `LIMIT` into a query with a `posts_per_page` of `-1`, so that result is now clamped to zero. For the same reason the unreachable `isset()` fallback in `WP_Sitemaps_Posts::get_max_num_pages()` is removed, retiring its baseline entry.

    Developed in https://github.com/WordPress/wordpress-develop/pull/15475.
    Follow-up to r48476, r57648, r61454, r65192.

    Props bgturner, westonruter.
    See #65817.

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


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

diff --git a/wp-includes/class-wp-query.php b/wp-includes/class-wp-query.php
index 88981421ff..2b593c0add 100644
--- a/wp-includes/class-wp-query.php
+++ b/wp-includes/class-wp-query.php
@@ -186,6 +186,7 @@ class WP_Query {
 	 *
 	 * @since 2.1.0
 	 * @var int
+	 * @phpstan-var int<0, max>
 	 */
 	public $max_num_pages = 0;

@@ -3732,7 +3733,7 @@ class WP_Query {
 		$this->found_posts = (int) apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );

 		if ( ! empty( $limits ) ) {
-			$this->max_num_pages = (int) ceil( $this->found_posts / $query_vars['posts_per_page'] );
+			$this->max_num_pages = max( 0, (int) ceil( $this->found_posts / (int) $query_vars['posts_per_page'] ) );
 		}
 	}

diff --git a/wp-includes/general-template.php b/wp-includes/general-template.php
index eb6e185f5b..f91680a9ef 100644
--- a/wp-includes/general-template.php
+++ b/wp-includes/general-template.php
@@ -4983,7 +4983,7 @@ function paginate_links( $args = '' ) {
 	$url_parts    = explode( '?', $pagenum_link );

 	// Get max pages and current page out of the current query, if available.
-	$total   = $wp_query->max_num_pages ?? 1;
+	$total   = $wp_query->max_num_pages;
 	$current = get_query_var( 'paged' ) ? (int) get_query_var( 'paged' ) : 1;

 	/*
diff --git a/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php b/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php
index c96b12c7e2..c1545c26b9 100644
--- a/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php
+++ b/wp-includes/sitemaps/providers/class-wp-sitemaps-posts.php
@@ -209,7 +209,7 @@ class WP_Sitemaps_Posts extends WP_Sitemaps_Provider {
 		$query = new WP_Query( $args );

 		$min_num_pages = ( 'page' === $post_type && 'posts' === get_option( 'show_on_front' ) ) ? 1 : 0;
-		return isset( $query->max_num_pages ) ? max( $min_num_pages, $query->max_num_pages ) : 1;
+		return max( $min_num_pages, $query->max_num_pages );
 	}

 	/**
diff --git a/wp-includes/version.php b/wp-includes/version.php
index a9004d9180..3b3a3e0843 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.2-beta4-65280';
+$wp_version = '7.2-beta4-65281';

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