Commit 03d61f082a for wordpress.org
commit 03d61f082afd6348fdd40a81aa253d4a54d09efe
Author: westonruter <westonruter@git.wordpress.org>
Date: Wed Sep 16 21:14:50 2026 +0000
Code Quality: Make `absint()` always return a non-negative int.
Passing `PHP_INT_MIN` made `abs()` overflow to a `float`, and passing a float beyond the integer range produced `int(0)`. In PHP 8.5 this also included a deprecation notice because the cast is not representable. Both are now capped at `PHP_INT_MAX`, which is the closest representable integer and equal to the `float` that used to come back, while a non-finite float short-circuits to `0` before any cast happens. The return value is therefore guaranteed, so the native `int` return type and the `non-negative-int` annotation reverted in r63158 are restored.
This is a behavior change for input the function never handled correctly: a caller relying on the old `float` or `int(0)` result for an out of range value now gets `PHP_INT_MAX` instead. The PHPStan baselines are regenerated for the narrowed return type.
Developed in https://github.com/WordPress/wordpress-develop/pull/12944.
Follow-up to r62647, r63158.
Props josephscott, westonruter, dmsnell, irozum, sawf1y.
See #65817, #65826.
Built from https://develop.svn.wordpress.org/trunk@63646
git-svn-id: http://core.svn.wordpress.org/trunk@62821 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-includes/load.php b/wp-includes/load.php
index 9d40745342..061754e8b4 100644
--- a/wp-includes/load.php
+++ b/wp-includes/load.php
@@ -1461,12 +1461,44 @@ function is_multisite() {
* Converts a value to non-negative integer.
*
* @since 2.5.0
+ * @since 7.2.0 The `int` return type was added. Finite values beyond the integer
+ * range are now capped at `PHP_INT_MAX` rather than overflowing.
+ * Non-finite values continue to return `0`, as `NAN` and `INF` have
+ * always cast to `0`; note that this includes numeric strings beyond
+ * the float range, such as `'1e309'`, which become `INF` when cast.
*
* @param mixed $maybeint Data you wish to have converted to a non-negative integer.
* @return int A non-negative integer.
+ * @phpstan-return non-negative-int
*/
-function absint( $maybeint ) {
- return abs( (int) $maybeint );
+function absint( $maybeint ): int {
+ if ( is_float( $maybeint ) ) {
+ if ( ! is_finite( $maybeint ) ) {
+ // Casting `NAN` or `INF` to int has produced `0` since PHP 7.0.
+ return 0;
+ }
+
+ if ( $maybeint <= (float) PHP_INT_MIN || $maybeint >= (float) PHP_INT_MAX ) {
+ // Casting a float beyond the integer range is unreliable and warns as of PHP 8.5.
+ return PHP_INT_MAX;
+ }
+ }
+
+ /*
+ * Casting from an unknown type is the entire contract of this function, so this conversion is
+ * deliberate: arrays, objects, and resources are converted exactly as PHP has always converted
+ * them here, and narrowing the type first would change long-standing behavior. PHPStan flags
+ * such casts for good reason, but that reasoning does not apply here; if the rule level is
+ * ever raised to 9, the resulting `cast.int` error will need to be ignored or baselined.
+ */
+ $maybeint = (int) $maybeint;
+
+ if ( PHP_INT_MIN === $maybeint ) {
+ // `abs( PHP_INT_MIN )` overflows to a float, as `PHP_INT_MAX` is one less than `-PHP_INT_MIN`.
+ return PHP_INT_MAX;
+ }
+
+ return abs( $maybeint );
}
/**
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 72c2fe3326..ca92e0be42 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-alpha-63645';
+$wp_version = '7.2-alpha-63646';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.