Categories
English articles fun misc Tech

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…

2 replies on “PHP – fooled me once again…”

Ja!! Das ist, was ich an PHP so liebe. Man _DARF_ sich schlicht weg auf gar nichts verlassen und muss alles nachlesen, weil alles anders ist als in anderen Programmiersprachen/-umgebungen … was sich aber auch wieder in der nächsten PHP-Version ändern kann. 😉

It seems to me that it is quite a basic error to perform a check on $result that is inconsistent for some of the possible values of $result. If $result gets its value from a get_sql(), the test on it should be made robust towards any conceivable output of get_sql().

OTOH, count(bool) returning 1 for both False and True is as (little) surprising as having it return 1 for a one-element list, regardless of the value of the element.

Leave a Reply

Your email address will not be published. Required fields are marked *