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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: dennis at theseminargroup dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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: Sat Dec 21 16:01:28 2024 UTC