Permalink
Browse files

Fix matchattr for local flags. Fixes #419

* Fix matchattr for local flags
Tcl matchattr command incorrectly returned true when checking against an invalid channel flag. This patch checks first checks if the channel flag is invalid and, if it is, returns false.
* Fix botflag matching and chanflag validating.
* Generate Tcl error on searching for invalid flags
* Reorder internal botflags to only change unused ones.
* Update matchattr docs with better usage examples
  • Loading branch information...
vanosg committed Nov 25, 2017
1 parent f0f2f08 commit dccd3fdb7847df3df124fd4ece11fb14f7053ad9
Showing with 62 additions and 34 deletions.
  1. +36 −12 doc/sphinx_source/mainDocs/tcl-commands.rst
  2. +1 −1 src/flags.c
  3. +12 −12 src/flags.h
  4. +13 −9 src/tcluser.c
@@ -305,7 +305,41 @@ botattr <handle> [changes [channel]]
matchattr <handle> <flags> [channel]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Returns: 1 if the specified user has the specified flags; 0 otherwise
Description: checks if the flags of the specified user match the flags provided. Default matching pattern uses the | (OR) convention. For example, specifying +mn for flags will check if the user has the m OR n flag.
+------------+-----------------------------------------------------------------+
| Flag Mask | Action |
+============+=================================================================+
| +m + Checks if the user has the m global flag |
+------------+-----------------------------------------------------------------+
| +mn | Checks if the user has the m or n global flag |
+------------+-----------------------------------------------------------------+
| +mn& | Checks if the user has the m and n global flag |
+------------+-----------------------------------------------------------------+
| \|+o #foo | Checks if the user has the o channel flag for #foo |
+------------+-----------------------------------------------------------------+
| &mn #foo | Checks if the user has the m and n channel flag for #foo |
+------------+-----------------------------------------------------------------+
| +o|+n #foo | Checks if the user has the o global flag, or the n channel |
| | flag for #foo |
+------------+-----------------------------------------------------------------+
| +m&+v | Checks if the user has the m global flag, and the v channel |
| | flag for #foo |
+------------+-----------------------------------------------------------------+
| -m | Checks if the user does not have the m global flag |
+------------+-----------------------------------------------------------------+
| \|-n #foo | Checks if the user does not have the n channel flag for #foo |
+------------+-----------------------------------------------------------------+
| +m|-n #foo | Checks if the user has the global m flag or does not have a |
| | channel n flag for #foo |
+------------+-----------------------------------------------------------------+
| -n&-m #foo | Searches if the user does not have the global n flag and does |
| | not have the channel m flag for #foo |
+------------+-----------------------------------------------------------------+
| ||+b | Searches if the user has the bot flag b |
+------------+-----------------------------------------------------------------+
Returns: 1 if the specified user has the flags matching the provided mask; 0 otherwise
Module: core
@@ -1168,17 +1202,7 @@ onchansplit <nick> [channel]
chanlist <channel> [flags][<&|>chanflags]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Description: flags are any global flags; the '&' or '|' denotes to look for channel specific flags, where '&' will return users having ALL chanflags and '|' returns users having ANY of the chanflags. Examples:
+--------+--------------------------------+
| n | (Global Owner) |
+--------+--------------------------------+
| &n | (Channel Owner) |
+--------+--------------------------------+
| o&m | (Global Op, Channel Master) |
+--------+--------------------------------+
Now you can use even more complex matching of flags, including +&- flags and & or | ('and' or 'or') matching.
Description: flags are any global flags; the '&' or '|' denotes to look for channel specific flags, where '&' will return users having ALL chanflags and '|' returns users having ANY of the chanflags (See matchattr above for additional examples).
Returns: Searching for flags optionally preceded with a '+' will return a list of nicknames that have all the flags listed. Searching for flags preceded with a '-' will return a list of nicknames that do not have have any of the flags (differently said, '-' will hide users that have all flags listed). If no flags are given, all of the nicknames on the channel are returned.
View
@@ -488,7 +488,7 @@ static int bot2str(char *string, int bot)
{
char x = 'a', *old = string;
while (x < 'v') {
while (x <= 'z') {
if (bot & 1)
*string++ = x;
x++;
View
@@ -46,16 +46,16 @@ struct flag_record {
* unused letters: is
*
* botflags:
* 0123456789ab????ghi??l???p?rs???????
* unused letters: cdefjkmnoqtuvwxyz
* a?????ghi??l???p?rs??0123456789?????
* unused letters: bcdefjkmnoqtuvwxyz
*
* chanflags:
* a??defg???klmno?qr??uv??yz + user defined A-Z
* unused letters: bchijpstwx
* a??defg???klmno?qr???vw?yz + user defined A-Z
* unused letters: bchijpstuw
*/
#define USER_VALID 0x03fbfeff /* Sum of all USER_ flags */
#define CHAN_VALID 0x03777c79 /* Sum of all CHAN_ flags */
#define BOT_VALID 0x7fe689C1 /* Sum of all BOT_ flags */
#define USER_VALID 0x003fbfeff /* Sum of all valid USER_ flags */
#define CHAN_VALID 0x003637c79 /* Sum of all valid CHAN_ flags */
#define BOT_VALID 0x07fe689C1 /* Sum of all valid BOT_ flags */
#define USER_AUTOOP 0x00000001 /* a auto-op */
@@ -108,11 +108,11 @@ struct flag_record {
#define BOT_AGGRESSIVE 0x00040000 /* s bot shares user files */
#define BOT_T 0x00080000 /* t unused */
#define BOT_U 0x00100000 /* u unused */
#define BOT_V 0x00200000 /* v unused */
#define BOT_W 0x00400000 /* w unused */
#define BOT_X 0x00800000 /* x unused */
#define BOT_Y 0x01000000 /* y unused */
#define BOT_Z 0x02000000 /* z unused */
#define BOT_V 0x80000000 /* v unused */
#define BOT_W 0x100000000 /* w unused */
#define BOT_X 0x200000000 /* x unused */
#define BOT_Y 0x400000000 /* y unused */
#define BOT_Z 0x800000000 /* z unused */
#define BOT_FLAG0 0x00200000 /* 0 user-defined flag #0 */
#define BOT_FLAG1 0x00400000 /* 1 user-defined flag #1 */
#define BOT_FLAG2 0x00800000 /* 2 user-defined flag #2 */
View
@@ -243,8 +243,8 @@ static int tcl_botattr STDVAR
static int tcl_matchattr STDVAR
{
struct userrec *u;
struct flag_record plus, minus, user;
int ok = 0, f;
struct flag_record plus = {0}, minus = {0}, user = {0};
int ok = 0, nom = 0;
BADARGS(3, 4, " handle flags ?channel?");
@@ -253,15 +253,19 @@ static int tcl_matchattr STDVAR
get_user_flagrec(u, &user, argv[3]);
plus.match = user.match;
break_down_flags(argv[2], &plus, &minus);
f = (minus.global || minus.udef_global || minus.chan || minus.udef_chan ||
minus.bot);
minus.match = plus.match ^ (FR_AND | FR_OR);
if (!minus.global && !minus.udef_global && !minus.chan &&
!minus.udef_chan && !minus.bot) {
nom = 1;
if (!plus.global && !plus.udef_global && !plus.chan &&
!plus.udef_chan && !plus.bot) {
Tcl_AppendResult(irp, "Unknown flag specified for matching", NULL);
return TCL_ERROR;
}
}
if (flagrec_eq(&plus, &user)) {
if (!f)
if (nom || !flagrec_eq(&minus, &user)) {
ok = 1;
else {
minus.match = plus.match ^ (FR_AND | FR_OR);
if (!flagrec_eq(&minus, &user))
ok = 1;
}
}
}

0 comments on commit dccd3fd

Please sign in to comment.