php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36799 Short cirquit AND evaluates like OR
Submitted: 2006-03-20 17:47 UTC Modified: 2006-03-21 19:54 UTC
From: cleo at anarki dot dk Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.1.2 OS: WinXP, Mandriva Linux 2006
Private report: No CVE-ID: None
 [2006-03-20 17:47 UTC] cleo at anarki dot dk
Description:
------------
Consider the following piece of code:
  $res= ($h>=0) and ($h<=23);
It could be used to determine if a user has submitted an hour between 0 and 23.

However, if the user enters 25, then the function evaluates to true!!!!

If you reverse the order of the operands like this:
  $res = ($h<=23) and ($h>=0);
...then a $h value of 25 will make the function evaluate to false.

But now -1 will make it evaluate to true!

So clearly, this must be a major bug.
Best regards
Claus Holm, Copenhagen, Denmark

Reproduce code:
---------------
<? if (isset($_POST['test'])) {
    $hours= $_POST['e_hours'];
    $hours= (integer)$hours;
    echo "You entered $hours <br>";
    echo 'Now we test: ($hours>=0) and ($hours<=23)<br>';
    $test1= ($hours>=0) and ($hours<=23);
    echo $test1 ? "ok" : "nope";
    echo "<br>";
    echo 'And now we test: ($hours<=23)and($hours>=0)<br>';
    $test2= ($hours<=23) and ($hours>=0);
    echo $test2 ? "ok" : "nope";
  }
  else {
?>  Input an hour between 0 and 23:<br>
    <FORM action="<?=$_SERVER['PHP_SELF']?>" method="post">
      <INPUT type="text" name="e_hours" value=""><br>
      <INPUT type="submit" name="test" value="Run test">
    </form>
<?}
?>


Expected result:
----------------
If the value 25 is entered, then I should see this:


You entered 25
Now we test: ($hours>=0) and ($hours<=23)
nope
And now we test: ($hours<=23) and ($hours>=0)
nope

Actual result:
--------------
You entered 25
Now we test: ($hours>=0) and ($hours<=23)
ok
And now we test: ($hours<=23) and ($hours>=0)
nope

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-03-20 18:09 UTC] tony2001@php.net
$h = 25;
$res = (($h>=0) and ($h<=23));
 [2006-03-20 19:59 UTC] cleo at anarki dot dk
All right, 
  ( (p1) and (p2) ) 
evaluates correctly,
but that doesn't change the fact, that 
  (p1) and (p2)
evaluates totally wrongly.
And I don't see the difference.
Neither from a mathematician's nor a computer scientist's point of view.
Therefore, I still strongly argue, that this is a bug in PHP's way of evaluating boolean expressions.

Best regards
Claus Holm from Copenhagen
 [2006-03-21 01:59 UTC] rasmus@php.net
The whole point of 'and','or' is to be the low-precedence version of '&&', '||'.  If you want high-precedence, use &&.
 [2006-03-21 09:18 UTC] cleo at anarki dot dk
Thanks Rasmus,

At last someone comes up with an explanation.
I can see the point of having to versions of boolean and, each with different precedence.

However, the precedence of 'and' should definitely not be lower than '='. 
What is your argument?

I mean:
  $test= true and false;
  echo $test ? "ok" : "nope";

I am sorry, but it can never be correct to let $test evaluate to true here!!!

As I see it, PHP does the following:
  ($test= true) and false
So, $test will be set to true, and the assignment will be true, and that assignment will be and'ed with false, and the result is discarded.
But who would want that?

Conclusion:
  $test1= true and false;  // Evaluates to true
  $test2= true && false;   // Evaluates to false

'=' and 'and' have wrong precedences in PHP.
One should always use && instead of 'and', as && used in an assignment statement gives the results you would expect from boolean algebra.
And 'and' does not.

Best regards, and the hope of recognition of my arguments
Claus Holm, Copenhagen, Denmark.
 [2006-03-21 10:11 UTC] rasmus@php.net
'and' and 'or' have the same precedence level.  

$foo = query() or die();

You need the = to be higher precedence here.

Also, please don't use our bug system as a support forum.
 [2006-03-21 19:33 UTC] cleo at anarki dot dk
Please, I *am* using the bug system to report a rather hideous bug.

You mention an example, where = needs to have higher precedence than or:
  $foo = query() or die();
Now, this is a smart hack one can use in the absence of proper error handling, like exception handling.
But it is a hack, and it messes up semantics: It says that if query() is false, then $foo should be assigned the value of die(). But this is not what happens because of how die() works.
It is, in my opinion, not an argument strong enough to overpower the hideous error that:
  $test= true and false;
evaluates to true.
Don't you agree with me, that this is unfortunate, to say the least?

Regards
Claus Holm, Copenhagen, Denmark
 [2006-03-21 19:54 UTC] rasmus@php.net
Nope, I don't agree.  It is fully consistent with the documented precedence order.  You should never use and/or over &&/|| unless you specifically want the lower precedence operator.  And this is not going to change as it would break thousands of scripts out there.

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri May 03 22:01:33 2024 UTC