Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix intval() and floatval() call with a non scalar value #2351

Merged
merged 3 commits into from Apr 19, 2023

Conversation

dravnic
Copy link
Contributor

@dravnic dravnic commented Apr 19, 2023

Here is a code snippet that shows a misleading error when intval() is used with a non-scalar.

<?php

class Foo
{
    private int $x = 0;
    
    function __construct() {
        $this->x += intval(new stdClass());
    }
}
8      Property Foo::$x (int) does not accept (float|int).  

It's reproducible with checkBenevolentUnionTypes: true

I've traced the issue.

intval() with non-scalar argument resolves to ErrorType which is inherited from MixedType.

So ErrorType::toNumber() returns UnionType of int and float. When above math expression is resolved it has int on the left side and float|int on the right side which produces error when checkBenevolentUnionTypes is on.

The root cause is fixed in this PR. It adds non-scalar value handling by making sure that return type for intval/floatval in all cases is int i.e. float.

PHP is throwing a warning on use of non-scalar with intval/floatval and not an error like with strval, so even though non-scalar arguments shouldn't be used we should handle them.

If non scalar value is used PHP will throw a warning,
not an error like with strval(), so intval/floatval
should return int i.e. float type in all cases.
@ondrejmirtes
Copy link
Member

Besides this it would also be nice to change the type of intval and floatval parameters to scalar in resources/functionMap.php. Because with non-scalars it produces a warning: https://3v4l.org/Bdim5

@dravnic
Copy link
Contributor Author

dravnic commented Apr 19, 2023

Makes sense. Just added it.

The above code now produces a proper error

Parameter #1 $value of function intval expects bool|float|int|string, stdClass given.

@ondrejmirtes ondrejmirtes merged commit 12ef4df into phpstan:1.10.x Apr 19, 2023
374 of 375 checks passed
@ondrejmirtes
Copy link
Member

Thank you!

@dravnic dravnic deleted the intval-floatval-non-scalar-arg branch April 19, 2023 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants