#65826 closed defect (bug) (fixed)
Avoid fatal error condition in absint()
| Reported by: | josephscott | Owned by: | westonruter |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.1 |
| Component: | General | Version: | 7.1 |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: |
Description
In https://github.com/WordPress/wordpress-develop/commit/395dd7422b a return type of int was added to absint(). But the return value of abs() is never checked, and it can return a float - https://www.php.net/abs - which would result in a PHP fatal error condition.
As a general rule we should always check return values. In this case we need to do that to avoid a conflict with the return type.
This is trivial to trigger with http://localhost:8889/?author=-99999999999999999999
Change History (17)
This ticket was mentioned in PR #12917 on WordPress/wordpress-develop by @josephscott.
5 weeks ago
#1
- Keywords has-patch has-unit-tests added
#2
@
5 weeks ago
- Milestone Awaiting Review → 7.1
- Owner set to
- Status new → reviewing
- Version → trunk
@sawf1y commented on PR #12917:
5 weeks ago
#3
Hi @josephscott . Nice potential bug revealing. Can you consider an option to cast $maybeint into a separate variable and check the new variable if it is float? This would avoid an unnecessary call to the abs() function.
@westonruter commented on PR #12917:
5 weeks ago
#4
The test failures are unrelated. See https://wordpress.slack.com/archives/C02RQBWTW/p1786058519099039?thread_ts=1786057730.714189&cid=C02RQBWTW
Should be fixed by merging in the latest from trunk.
@westonruter commented on PR #12917:
5 weeks ago
#5
@dmsnell Yeah, this has opened a can of worms or gone down a rabbit hole… maybe a wormhole?
The issue is that absint() was previously broken previously in two ways:
- Passing
PHP_INT_MINwould actually cause the function to return a _float_! - Passing anything above
PHP_INT_MAX(or belowPHP_INT_MIN) would cause it to returnint(0), and in PHP 8.5 a warning would also be emitted.
See https://3v4l.org/ZsvNQ#veol
For reference:
I tried your suggestion with fn ( $maybeint ) => min( PHP_INT_MAX, abs( (int) $maybeint ) ), but it doesn't seem improved: https://3v4l.org/VMXR3#v8.5.9
@dmsnell commented on PR #12917:
5 weeks ago
#6
@westonruter @josephscott how about we revert the type annotation addition which caused the fatals to appear and then tackle this more complicated issue as an enhancement?
@westonruter commented on PR #12917:
5 weeks ago
#7
@dmsnell Yeah, I support that. Since we're now in RC, it makes sense.
@josephscott Could you create a new PR which cherry-picks your original commit e549981f76c4d92d644a54754c15a19224326d61? We can then leave this original PR open for the 7.2 bugfix. If you could open a Trac ticket too that would great.
This ticket was mentioned in PR #12940 on WordPress/wordpress-develop by @dmsnell.
5 weeks ago
#8
Trac ticket: Core-65826
Replaces #12917
This reverts commit 395dd7422b1b569936bb8c0f9b90bf44d2044095.
When the return-type annotation was added to absint() it failed to recoginize that the function can return float as well. In the cases where it does this, WordPress started crashing requests.
Reverting remove the type constraint where PHP enforces it in order to avoid the fatal errors.
@dmsnell commented on PR #12917:
5 weeks ago
#9
@westonruter I’ve proposed a revert of the original commit in #12940 so that we can step back and address this with more space to consider it.
The original patch on this PR introduced a small behavioral change, so I think it would be ideal to pull back for 7.1 and allow more opportunity for testing and review into 7.2.
@westonruter commented on PR #12917:
5 weeks ago
#10
Makes sense to me. Revert PR approved ✅
@dmsnell commented on PR #12917:
5 weeks ago
#11
Closing in favor of #12940. Thanks @josephscott — I’ll merge the revert into 7.1 as soon as the CI tests pass.
@westonruter commented on PR #12917:
5 weeks ago
#12
I'll re-open this as it can serve as the basis for fixing the defect. If you want to start fresh, feel free to close again.
@josephscott commented on PR #12917:
5 weeks ago
#13
Might be worth starting a new PR for this, we can still reference https://core.trac.wordpress.org/ticket/65826
This ticket was mentioned in PR #12944 on WordPress/wordpress-develop by @josephscott.
4 weeks ago
#15
With a long list of tests
https://core.trac.wordpress.org/ticket/65826
This will cause return values to change compared to the old absint() - https://3v4l.org/MssWC - because the old one wasn't actually limited to returning only an int
AI assistance: Yes
Tool(s): Claude
Model(s): Fable 5
Used for: Discussion on potential approaches on how to fix absint() to only return an int in a more simplified way. Claude also wrote all of the new tests.
#16
@
4 weeks ago
Took another attempt at making sure that absint() only returns an int - https://github.com/WordPress/wordpress-develop/pull/12944
After some rubber ducking with Claude how this might be done in a more simple fashion I ended up settling on this.
This will change the return values that absint() gives compared to the original version https://3v4l.org/MssWC - which I think is the right move given the name of the function, but has the potential to impact code that might have come to rely on absint() not always returning an int.
@westonruter @dmsnell
#17
@
4 weeks ago
Note: I've opened https://github.com/phpstan/phpstan/issues/15069 to report the issue where PHPStan was not flagging that abs( (int) $value ) can return a float.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
https://core.trac.wordpress.org/ticket/65826
AI assistance: Yes
Tool(s): Claude
Model(s): Opus 4.8
Used for: I had Claude update the tests