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
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: 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

Pull Requests

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-2025 The PHP Group
All rights reserved.
Last updated: Tue Mar 11 19:01:31 2025 UTC