Skip to content

Conversation

Girgias
Copy link
Member

@Girgias Girgias commented Sep 8, 2025

@Girgias Girgias force-pushed the 8.5-warn-oob-float-to-int branch from 30d87e1 to acba14f Compare September 20, 2025 15:28
Comment on lines 915 to 923
ZEND_API void ZEND_COLD zend_oob_string_to_long_error(double d)
{
zend_error_unchecked(E_WARNING, "non-representable float-string %.*H was cast to int", -1, d);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It would be helpful if we could print the original string here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is possible for a non-float string to reach this part 🤔 but I could still add it as there only 2 calls to it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is that for code like echo (int) "10000000000000000000.0";, a warning such as non-representable float-string 10000000000000000000.0 was cast to int would be slightly more helpful than non-representable float-string 1.0E+19 was cast to int.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that is indeed true. Will see what I can do :)

@Girgias Girgias force-pushed the 8.5-warn-oob-float-to-int branch from acba14f to c54fc7a Compare September 21, 2025 12:02
@Girgias Girgias requested a review from a team September 21, 2025 12:40
@Girgias Girgias marked this pull request as ready for review September 21, 2025 13:15
@Girgias Girgias requested a review from arnaud-lb September 21, 2025 13:21
Copy link
Member

@arnaud-lb arnaud-lb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@nielsdos
Copy link
Member

Non-representable float is incorrect wording and very confusing. The float is representable, it just doesn't fit when you cast.

@Girgias
Copy link
Member Author

Girgias commented Sep 21, 2025

Non-representable float is incorrect wording and very confusing. The float is representable, it just doesn't fit when you cast.

Would:

The float %F is not representable as an int, cast occured in %s on line %d

be better?

@nielsdos
Copy link
Member

Non-representable float is incorrect wording and very confusing. The float is representable, it just doesn't fit when you cast.

Would:

The float %F is not representable as an int, cast occured in %s on line %d

be better?

Yes

Copy link
Member

@DanielEScherzer DanielEScherzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RM review: is this new warning meant to replace the existing deprecation? That doesn't appear to have been part of the RFC

@Girgias
Copy link
Member Author

Girgias commented Sep 21, 2025

RM review: is this new warning meant to replace the existing deprecation? That doesn't appear to have been part of the RFC

It doesn't replace the existing deprecation as this is only for implicit coercions to integer, this is for explicit casts for values that are not representable by a PHP int, and is what is specified in https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int

@DanielEScherzer
Copy link
Member

RM review: is this new warning meant to replace the existing deprecation? That doesn't appear to have been part of the RFC

It doesn't replace the existing deprecation as this is only for implicit coercions to integer, this is for explicit casts for values that are not representable by a PHP int, and is what is specified in https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int

In the tests (e.g. Zend/tests/bitwise_not_precision_exception.phpt) the output changes to replace the existing deprecation with a new warning, with no input code change, implying that the deprecation is replaced in at least some cases with a new warning

@Girgias
Copy link
Member Author

Girgias commented Sep 21, 2025

RM review: is this new warning meant to replace the existing deprecation? That doesn't appear to have been part of the RFC

It doesn't replace the existing deprecation as this is only for implicit coercions to integer, this is for explicit casts for values that are not representable by a PHP int, and is what is specified in https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int

In the tests (e.g. Zend/tests/bitwise_not_precision_exception.phpt) the output changes to replace the existing deprecation with a new warning, with no input code change, implying that the deprecation is replaced in at least some cases with a new warning

This is because the bitwise operators do an integer cast internally. And the value that is being cast is out of range, if you replace the value with 25.6 you would still get the deprecation rather than a warning. This is also the case for the % operator or any other internal function that does a force cast to int.

The operations that emit the deprecation introduced by https://wiki.php.net/rfc/implicit-float-int-deprecate had as a primary intention to prevent floats with fractional parts to be coerced implicitly into an integer as you lose the fractional part.
By design this also handles floats that are not representable as ints.

I am struggling to see what the issue here is, this RFC indicates that explicit casts (be that made by the engine or userland) should warn. Requiring that explicit casts warn is a stronger requirement than implicit casts, and having diverging behaviour between implicit and explicit casts doesn't make sense to me.

So yes, an implicit cast of an OOB float now warns, but implicit casts of representable floats continues to emit a deprecation while explicit casts of representable floats continue to be silent.

Copy link
Member

@DanielEScherzer DanielEScherzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RM review: is this new warning meant to replace the existing deprecation? That doesn't appear to have been part of the RFC

It doesn't replace the existing deprecation as this is only for implicit coercions to integer, this is for explicit casts for values that are not representable by a PHP int, and is what is specified in https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int

In the tests (e.g. Zend/tests/bitwise_not_precision_exception.phpt) the output changes to replace the existing deprecation with a new warning, with no input code change, implying that the deprecation is replaced in at least some cases with a new warning

This is because the bitwise operators do an integer cast internally. And the value that is being cast is out of range, if you replace the value with 25.6 you would still get the deprecation rather than a warning. This is also the case for the % operator or any other internal function that does a force cast to int.

The operations that emit the deprecation introduced by https://wiki.php.net/rfc/implicit-float-int-deprecate had as a primary intention to prevent floats with fractional parts to be coerced implicitly into an integer as you lose the fractional part. By design this also handles floats that are not representable as ints.

I am struggling to see what the issue here is, this RFC indicates that explicit casts (be that made by the engine or userland) should warn. Requiring that explicit casts warn is a stronger requirement than implicit casts, and having diverging behaviour between implicit and explicit casts doesn't make sense to me.

So yes, an implicit cast of an OOB float now warns, but implicit casts of representable floats continues to emit a deprecation while explicit casts of representable floats continue to be silent.

No issue I guess, I was just confused as to if this was expected because there were existing warnings that were being replaced


RM approval, technical review not performed

@Girgias Girgias merged commit b4ed215 into php:master Sep 21, 2025
9 checks passed
@Girgias Girgias deleted the 8.5-warn-oob-float-to-int branch September 21, 2025 22:53
nicolas-grekas added a commit to symfony/symfony that referenced this pull request Sep 26, 2025
…n/max int ranges (xabbuh)

This PR was merged into the 6.4 branch.

Discussion
----------

[DoctrineBridge][Yaml] don't cast strings exceeding the min/max int ranges

| Q             | A
| ------------- | ---
| Branch?       | 6.4
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Issues        |
| License       | MIT

see php/php-src#19760 and https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int

Commits
-------

bac84d1 don't cast strings exceeding the min/max int ranges
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants