// Hi, I want to exclude a flag with bitwise operations, but I don't know how : // Here are the flags (they come from filesystemiterator)
define('CURRENT_AS_FILEINFO', 0);
define('CURRENT_AS_SELF', 16);
define('CURRENT_AS_PATHNAME', 32);
define('CURRENT_MODE_MASK', 240);
define('KEY_AS_PATHNAME', 0);
define('KEY_AS_FILENAME', 256);
define('FOLLOW_SYMLINKS', 512);
define('KEY_MODE_MASK', 3840);
define('NEW_CURRENT_AND_KEY', 256);
define('SKIP_DOTS', 4096);
define('UNIX_PATHS', 8192);
The user can potentially set any combination of flags. I need to detect if CURRENT_AS_SELF or CURRENT_AS_PATHNAME was set, so here is my function so far:
function containsPathnameOrSelfFlag($flags) {
if ($flags & (CURRENT_AS_PATHNAME | CURRENT_AS_SELF)) {
return true;
}
return false;
}
And here is a test suite :
var_dump(containsPathnameOrSelfFlag(CURRENT_MODE_MASK | CURRENT_AS_PATHNAME)); // true, ok
var_dump(containsPathnameOrSelfFlag(CURRENT_AS_FILEINFO)); // false, ok
var_dump(containsPathnameOrSelfFlag(CURRENT_MODE_MASK | CURRENT_AS_FILEINFO)); // true, but false was expected, because neither CURRENT_AS_SELF nor CURRENT_AS_SELF were set, so my function is wrong
Is it possible to use bitwise operators to make the function pass the third case ( it should return false ) ?
The problem I see here is that the CURRENT_MODE_MASK's bit overlap the CURRENT_AS_SELF and CURRENT_AS_PATHNAME's bits :
0000000000010000 : CURRENT_AS_SELF
0000000000100000 : CURRENT_AS_PATHNAME
0000000011110000 : CURRENT_MODE_MASK
0000000100000000 : KEY_AS_FILENAME
0000001000000000 : FOLLOW_SYMLINKS
0000111100000000 : KEY_MODE_MASK
0000000100000000 : NEW_CURRENT_AND_KEY
0001000000000000 : SKIP_DOTS
0010000000000000 : UNIX_PATHS
So every time the user add the CURRENT_MODE_MASK to the flags, my function will think that the CURRENT_AS_SELF and the CURRENT_AS_PATHNAME were set too, though it's not the case. I don't know how to solve this.
0000000011000000KEY_MODE_MASKis technically not set to the correct value, sinceKEY_MODE_MASK & FOLLOW_SYMLINKSreturns a truthy result, even thoughFOLLOW_SYMLINKSisn't related to any of the key flags. Thus having$any_key_flag_set = $fsiObj->getFlags() & $fsiObj::KEY_MODE_MASK;would return a false positive.KEY_MODE_MASKought to be 3328 (removing 512 from its mask), orFOLLOW_SYMLINKSshould be 16384 to get it out of the 3840 mask.