Hi, today, we discovered a couple of cases like this in a code:
if($this->randomObject>getError()){
]
Unfortunately for us, we have both a getError function in global namespace AND getError methods on some objects.
It would be cool to match this kind of errors. Maybe match every object in the first operand with a ">" operator and match if the function exists as a method in the object?
We were able to find some with a regex on this specific function but it's hard to find every possible case...
Thanks!
It is very hard identify cases like that, because you could really wants to check if $this->randomObject > getError(). So maybe it could be checked by another way:
> without spaces. But it could be a problem if you really prefer codes like that or if you use autoformatting that will add spaces between it automatically;> will return int, so if getError() returns a string, for instance, it probabily is a mistake;The second case is the most probable to work without too much false-positives, but will requires that you set a return typehint for getError() (at least the global one).
Well, I'm not sure there would be this much false positives, we're talking about this operation:
(object) > (string|int|float|bool|object)
Which means, on the best scenario, we will call __toString and then cast __toString's return to be able to perform the comparison. I don't remember ever seeing this usage of __toString in a real project. Even less so with a function name defined both in global namespace and in the object...
On the worst scenario, __toString won't be defined and we will perform a weird operation on an object (i'm not even sure what it does...):
https://3v4l.org/S6Op3
It could be an upgrade to "suspicious binary operations" inspection. It currently do this check, but only for inline values (eg. $x > [], but not for $x > $anArray). What do you think @kalessil?
// Given:
$aString = 'test';
$anInteger = 123;
$aFloat = 1.23;
$aBoolean = true;
$anArray = [];
$anObject = new stdclass;
$aNulll = null;
$aResource = mysql_connect();
So: $aBoolean | $anArray | $anObject | $aNull | $aResource should not allow > | >= | < | <= in any side.
An additional exception should be treated for $anObject because it could implements __toString(), but I think that only in this case it could be ignored.
Implemented!
@rentalhost : checked your input, we run into type resolver limitations there. While inlined values are relatively reliable criteria for firing analysis, supporting more generic case will be a huge piece of maintenance efforts.
But I didi hear that this year we might see a new type resolver implementation.
Cool!
Most helpful comment
It could be an upgrade to "suspicious binary operations" inspection. It currently do this check, but only for inline values (eg.
$x > [], but not for$x > $anArray). What do you think @kalessil?So:
$aBoolean | $anArray | $anObject | $aNull | $aResourceshould not allow> | >= | < | <=in any side.An additional exception should be treated for
$anObjectbecause it could implements__toString(), but I think that only in this case it could be ignored.