Skip to content

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

Merged
ondrejmirtes merged 3 commits intophpstan:1.10.xfrom
giscloud:intval-floatval-non-scalar-arg
Apr 19, 2023
Merged

Fix intval() and floatval() call with a non scalar value#2351
ondrejmirtes merged 3 commits intophpstan:1.10.xfrom
giscloud:intval-floatval-non-scalar-arg

Conversation

@dravnic
Copy link
Copy Markdown
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.

dravnic added 2 commits April 19, 2023 15:07
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
Copy Markdown
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
Copy Markdown
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
@ondrejmirtes
Copy link
Copy Markdown
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

Development

Successfully merging this pull request may close these issues.

2 participants