php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76744 &, |, and ^ miscalculate from POST/GET integers
Submitted: 2018-08-15 02:56 UTC Modified: 2018-08-15 09:18 UTC
From: dennis at theseminargroup dot com Assigned: cmb (profile)
Status: Not a bug Package: Variables related
PHP Version: Irrelevant OS: Linux x86_64 Ubuntu 18.04
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
37 + 9 = ?
Subscribe to this entry?

 
 [2018-08-15 02:56 UTC] dennis at theseminargroup dot com
Description:
------------
Isn't PHP supposed to convert string-integers to binary-integers internally whenever it needs to? I discovered serious calculation errors from AND, OR, and XOR bitwise operators when operating on certain small integers from data submitted from html forms by POST or GET. For example, 16 & 13 = 12, according to PHP, when these are from $_GET or $_POST. 16 & 13 = 0 when calculated from locally-assigned variables. See short demonstration script below.

Miscalculations could create serious problems for PHP users if you're depending on correct answers. Discovered on php 7.2.7-0ubuntu0.18.04.2 and also tested on old php versions 4.3.2 and 5.0.4 with identical results.

Functions + and - tested and work correctly. Seems to only affect bitwise operators. Please accept my profound apologies if I merely missed something in the fine PHP manual. I'm certain you can reproduce these results 100%. Thanks for reading this.

Test script:
---------------
<?php // calctest.php bit-wise calculator bug demonstration. PHP is supposed to
// convert string integers to binary integers whenever it needs to, right? This
// doesn't appear to be true for &, | and ^ (and, or, and xor). 8/14/2018.
if (isset ($_GET['a'])) // same results if using $_POST variables
    $a = $_GET['a'];
if (isset ($_GET['b']))
    $b = $_GET['b'];
if (!isset ($a) || !isset ($b)) {
    echo "invoke as calctest.php?a=29&b=11<br>\n";
    echo "Use different small integers as desired<br>\n";
    exit; }
printf ("%d & %d = %d<br>\n", $a, $b, $a & $b);
printf ("%d | %d = %d<br>\n", $a, $b, $a | $b);
printf ("%d ^ %d = %d<br>\n", $a, $b, $a ^ $b);
$c = intval ($a); // force converstion to binary and try again
$d = intval ($b);
printf ("<br>Real Answers:</br>\n");
printf ("%d & %d = %d<br>\n", $c, $d, $c & $d);
printf ("%d | %d = %d<br>\n", $c, $d, $c | $d);
printf ("%d ^ %d = %d<br>\n", $c, $d, $c ^ $d); ?>


Expected result:
----------------
Correct results were expected. For example, calctest.php?a=16&b=13
16 & 13 = 12 (wrong)
16 | 13 = 17 (wrong)
16 ^ 13 = 0  (wrong)

Real Answers:
16 & 13 = 0 (correct)
16 | 13 = 29 (correct)
16 ^ 13 = 29 (correct)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-08-15 03:33 UTC] a at b dot c dot de
Quoth the manual: " If both operands for the &, | and ^ operators are strings, then the operation will be performed on the ASCII values of the characters that make up the strings and the result will be a string. In all other cases, both operands will be converted to integers and the result will be an integer. "

Since request variables are strings, bitwise operations on them are performed bytewise.
 [2018-08-15 09:18 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2018-08-15 09:18 UTC] cmb@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

See also <https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#bitwise-and-operator>.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon May 27 22:01:33 2024 UTC