PHP – fooled me once again…

I was asked to take a look at several free and opensource software web-projects which are capable for so called “ISP configuration management”, managing web-, mail-, database-servers, etc. – handling clients, resellers and admins and having specialized frontends for them…

Anyway… I trigerred a weird bug in one of the projects where I got into an if-condition where I shouldn’t get into… which not just caused a weird behaviour of the application but was also a big security hole in this special case.

The code was something like that (simplified and not tested):


get_sql($value) {
   if ($ret = mysql_query ("SELECT * FROM `table` WHERE foo='%s'"),
       mysql_real_escape_string($value))
   {
     return $ret;
   }
   else
   {
     return false;
   }
}
<br />
$result = get_sql($foo);
if (count($result) &gt; 0) {
&nbsp;&nbsp; // privileged area...
}

Ugly code – anyway… how it was expected to behave by the author?
1) function get_sql() gets executed and therefore a sql-query
2) get_sql() returns an array of results
3) the number of results is checked via count($result) and when the result-array is greater than 0 jump into the if-block

Okay, so far so good…

However – I finally found out the SQL-query in get_sql() fails because of a typo.
No error was thrown in the above code – so what’s happening?
1) function get_sql() gets executed and therefore a sql-query
2) get_sql() returns the boolean false, because the sql-query failed
3) count($result), evaluated count(false) is called

As the software just did behave different and didn’t throw an error an intermediate result is:

count() applied on a boolean is valid !

So what’s count(false) going to return?

1! – the integer one!

count(false) is 1 and in PHP therefore true!

Proof:


$ php
&lt;? echo count(false); ?&gt;
1
$

Even better: this behaviour is kind of “documented” within an example at http://php.net/manual/en/function.count.php without any comment.

Okay, now guess:
What’s count(true) returning? And this is not documented!

1! – the integer one!

PHP – dine in hell…