From 33f7da899013930b530379ecd09bf109e50e4148 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 5 Sep 2026 13:13:35 +0200 Subject: [PATCH 1/2] Update PHPStan 2.2.13 --- composer.json | 2 +- src/wp-includes/formatting.php | 4 ---- tests/phpstan/baselines/argument.type.neon | 10 ++++++++++ tests/phpstan/baselines/empty.variable.neon | 5 ----- .../function.alreadyNarrowedType.neon | 20 +++++++++---------- tests/phpstan/baselines/if.alwaysFalse.neon | 5 ----- .../phpstan/baselines/property.notFound.neon | 2 +- 7 files changed, 22 insertions(+), 26 deletions(-) diff --git a/composer.json b/composer.json index 34a8d980259f1..06edbbf0e776d 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "squizlabs/php_codesniffer": "3.13.5", "wp-coding-standards/wpcs": "~3.4.1", "phpcompatibility/phpcompatibility-wp": "~2.1.3", - "phpstan/phpstan": "2.2.5", + "phpstan/phpstan": "2.2.13", "phpstan/phpstan-phpunit": "2.0.18", "yoast/phpunit-polyfills": "^1.1.0" }, diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 1c0b62cf1e14f..b9d551d59d51b 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4848,10 +4848,6 @@ function esc_xml( $text ) { $safe_text = (string) preg_replace_callback( $regex, static function ( $matches ) { - if ( ! isset( $matches[0] ) ) { - return ''; - } - if ( isset( $matches['non_cdata'] ) ) { // escape HTML entities in the non-CDATA Section. return _wp_specialchars( $matches['non_cdata'], ENT_XML1 ); diff --git a/tests/phpstan/baselines/argument.type.neon b/tests/phpstan/baselines/argument.type.neon index 66bfb6d6b9585..263396f58694c 100644 --- a/tests/phpstan/baselines/argument.type.neon +++ b/tests/phpstan/baselines/argument.type.neon @@ -773,6 +773,11 @@ parameters: identifier: argument.type count: 2 path: ../../../src/wp-includes/class-wp-embed.php + - + message: '#^Parameter \#1 \$handle of function curl_getinfo expects resource, \(resource\|false\) given\.$#' + identifier: argument.type + count: 2 + path: ../../../src/wp-includes/class-wp-http-curl.php - message: '#^Parameter \#3 \$value of function curl_setopt expects int, string given\.$#' identifier: argument.type @@ -928,6 +933,11 @@ parameters: identifier: argument.type count: 1 path: ../../../src/wp-includes/formatting.php + - + message: '#^Parameter \#1 \$finfo of function finfo_file expects resource, resource\|false given\.$#' + identifier: argument.type + count: 2 + path: ../../../src/wp-includes/functions.php - message: '#^Parameter \#1 \$prefix of function uniqid expects string, int\<0, max\> given\.$#' identifier: argument.type diff --git a/tests/phpstan/baselines/empty.variable.neon b/tests/phpstan/baselines/empty.variable.neon index 28186fb9fc850..ba4af02b326c1 100644 --- a/tests/phpstan/baselines/empty.variable.neon +++ b/tests/phpstan/baselines/empty.variable.neon @@ -23,11 +23,6 @@ parameters: identifier: empty.variable count: 1 path: ../../../src/wp-admin/includes/class-wp-posts-list-table.php - - - message: '#^Variable \$title in empty\(\) always exists and is always falsy\.$#' - identifier: empty.variable - count: 1 - path: ../../../src/wp-admin/includes/plugin.php - message: '#^Variable \$parent_file in empty\(\) always exists and is not falsy\.$#' identifier: empty.variable diff --git a/tests/phpstan/baselines/function.alreadyNarrowedType.neon b/tests/phpstan/baselines/function.alreadyNarrowedType.neon index 5d0293fde3b5b..f6735d7575dc0 100644 --- a/tests/phpstan/baselines/function.alreadyNarrowedType.neon +++ b/tests/phpstan/baselines/function.alreadyNarrowedType.neon @@ -23,11 +23,6 @@ parameters: identifier: function.alreadyNarrowedType count: 2 path: ../../../src/wp-admin/includes/ajax-actions.php - - - message: '#^Call to function is_wp_error\(\) with WP_Error will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../src/wp-admin/includes/ajax-actions.php - message: '#^Call to function method_exists\(\) with ''ParagonIE_Sodium…'' and ''runtime_speed_test'' will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -48,11 +43,6 @@ parameters: identifier: function.alreadyNarrowedType count: 1 path: ../../../src/wp-admin/includes/plugin.php - - - message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../src/wp-includes/block-editor.php - message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#' identifier: function.alreadyNarrowedType @@ -78,6 +68,16 @@ parameters: identifier: function.alreadyNarrowedType count: 1 path: ../../../src/wp-includes/functions.php + - + message: '#^Call to function is_scalar\(\) with string will always evaluate to true\.$#' + identifier: function.alreadyNarrowedType + count: 3 + path: ../../../src/wp-includes/functions.php + - + message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#' + identifier: function.alreadyNarrowedType + count: 1 + path: ../../../src/wp-includes/functions.php - message: '#^Call to function is_array\(\) with array will always evaluate to true\.$#' identifier: function.alreadyNarrowedType diff --git a/tests/phpstan/baselines/if.alwaysFalse.neon b/tests/phpstan/baselines/if.alwaysFalse.neon index 2675668db7b5d..6e33ed2a5365c 100644 --- a/tests/phpstan/baselines/if.alwaysFalse.neon +++ b/tests/phpstan/baselines/if.alwaysFalse.neon @@ -28,11 +28,6 @@ parameters: identifier: if.alwaysFalse count: 2 path: ../../../src/wp-includes/class-wp-block-processor.php - - - message: '#^If condition is always false\.$#' - identifier: if.alwaysFalse - count: 1 - path: ../../../src/wp-includes/load.php - message: '#^If condition is always false\.$#' identifier: if.alwaysFalse diff --git a/tests/phpstan/baselines/property.notFound.neon b/tests/phpstan/baselines/property.notFound.neon index f4288f6aa6aff..c7d60d13061d2 100644 --- a/tests/phpstan/baselines/property.notFound.neon +++ b/tests/phpstan/baselines/property.notFound.neon @@ -176,7 +176,7 @@ parameters: - message: '#^Access to an undefined property WP_Theme\:\:\$version\.$#' identifier: property.notFound - count: 5 + count: 6 path: ../../../src/wp-admin/includes/class-wp-debug-data.php - message: '#^Access to an undefined property WP_Theme\:\:\$auto_update_forced\.$#' From 09218f698a8a7b4c44c9214666267d3a97eb7397 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 6 Sep 2026 17:01:36 -0700 Subject: [PATCH 2/2] Document the integer message passthrough in _wp_die_process_input() wp_die() accepts an integer message, which the legacy Ajax handlers use for their -1/0/1 responses, and _wp_die_process_input() passes it through untouched since only a WP_Error is rewritten. Its docblock only admitted string|WP_Error, so the processed message was typed as a plain string and PHPStan 2.2.13 reported the is_string() and is_scalar() guards in the wp_die() handlers as always true. Type the parameter as string|WP_Error|int and the first element of the returned hash as string|int. The is_string() check in _default_wp_die_handler() is now reachable and leaves the baseline; the three is_scalar() entries remain, with their message updated to reflect the int|string type, since int|string is always scalar. Co-Authored-By: Claude Fable 5.1 --- src/wp-includes/functions.php | 12 ++++++------ .../baselines/function.alreadyNarrowedType.neon | 7 +------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 1f29dfb5f29ab..f5678afdbda2a 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -4360,15 +4360,15 @@ function _scalar_wp_die_handler( $message = '', $title = '', $args = array() ) { * @since 5.1.0 * @access private * - * @param string|WP_Error $message Error message or WP_Error object. - * @param string $title Optional. Error title. Default empty string. - * @param string|array $args Optional. Arguments to control behavior. Default empty array. + * @param string|WP_Error|int $message Error message, WP_Error object, or integer response. + * @param string $title Optional. Error title. Default empty string. + * @param string|array $args Optional. Arguments to control behavior. Default empty array. * @return array { * Processed arguments. * - * @type string $0 Error message. - * @type string $1 Error title. - * @type array $2 Arguments to control behavior. + * @type string|int $0 Error message, or integer response. + * @type string $1 Error title. + * @type array $2 Arguments to control behavior. * } */ function _wp_die_process_input( $message, $title = '', $args = array() ) { diff --git a/tests/phpstan/baselines/function.alreadyNarrowedType.neon b/tests/phpstan/baselines/function.alreadyNarrowedType.neon index f6735d7575dc0..729054d7bfc1f 100644 --- a/tests/phpstan/baselines/function.alreadyNarrowedType.neon +++ b/tests/phpstan/baselines/function.alreadyNarrowedType.neon @@ -69,15 +69,10 @@ parameters: count: 1 path: ../../../src/wp-includes/functions.php - - message: '#^Call to function is_scalar\(\) with string will always evaluate to true\.$#' + message: '#^Call to function is_scalar\(\) with int\|string will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 3 path: ../../../src/wp-includes/functions.php - - - message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../../src/wp-includes/functions.php - message: '#^Call to function is_array\(\) with array will always evaluate to true\.$#' identifier: function.alreadyNarrowedType