php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63792 Bitset::andOp does multiple ANDs between the same octects
Submitted: 2012-12-17 23:56 UTC Modified: 2017-10-24 08:00 UTC
From: harroyo at hangar18 dot cc Assigned:
Status: Open Package: Bitset (PECL)
PHP Version: Irrelevant OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: harroyo at hangar18 dot cc
New email:
PHP Version: OS:

 

 [2012-12-17 23:56 UTC] harroyo at hangar18 dot cc
Description:
------------
See https://github.com/php/pecl-numbers-bitset/blob/master/bitset.c#L279 : the 
loop that 
performs the AND looks like this:

for (; i < to_bits; i++) {
	intern->bitset_val[i / CHAR_BIT] &= param->bitset_val[i / CHAR_BIT];
}

so taking, for example, CHAR_BIT=8, it does
 (intern[0] & param[0]),
 1/8=0 -> (intern[0] & param[0])
 2/8=0 -> (intern[0] & param[0])
 ...
 8/8=1 -> (intern[1] & param[1])

ie, it does AND CHAR_BIT times for every char. My suggested fix is to change the 
loop to 
something like this:

for (; i < to_bits; i+= CHAR_BIT) {
	intern->bitset_val[i / CHAR_BIT] &= param->bitset_val[i / CHAR_BIT];
}

//last increment may have set i above the bitset(s) bounds(and made the for loop 
skip 
last bits): operate on the last octect bit by bit

i = (to_bits/CHAR_BIT) * CHAR_BIT; // get the index of the last bit on a char 
boundary

for (unsigned char mask=0x0; i < to_bits; i++) {
        // bitwise and one bit at a time
        // please note the following code is not tested

        mask = ~(1 << (i%CHAR_BITS)); // all bits set to 1 except the current 
index
        mask |= param->bitset_val[i / CHAR_BIT]; // all 1s if the current index 
is set, 
mask unchanged if not

	intern->bitset_val[i / CHAR_BIT] &= mask; //changes only the current bit
}




Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-12-18 00:15 UTC] harroyo at hangar18 dot cc
Note also if bitset_len1 > bitset_len2, then IMO the remaining (len1-len2) bits 
from intern->bitset_val should be set to zero (because semantically it would be 
equivalent to ANDing with NULL, and (anything&NULL)==false).
 [2012-12-18 00:24 UTC] harroyo at hangar18 dot cc
the mask'ing part inside the loop can be condensed, similar to 
https://github.com/php/pecl-numbers-bitset/blob/master/bitset.c#L591
 [2012-12-18 21:12 UTC] willfitch@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: willfitch
 [2017-10-24 08:00 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: willfitch +Assigned To:
 [2022-12-24 09:24 UTC] sheyda dot babi5161 at gmail dot com
I also faced same issue but now it solved for me. (https://www.conduent-connect.net/)github.com
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 06:01:30 2024 UTC