1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-26 04:46:37 +02:00

irc: add support of UTF8MAPPING, add support of optional server in info "irc_is_nick" (closes #1528)

This commit is contained in:
Sébastien Helleu
2020-06-20 17:28:28 +02:00
parent bf964de939
commit 12051a506d
34 changed files with 389 additions and 132 deletions
+20 -2
View File
@@ -108,6 +108,10 @@ irc_info_info_irc_is_nick_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *pos_comma, *server;
const char *pos_nick;
struct t_irc_server *ptr_server;
/* make C compiler happy */
(void) pointer;
(void) data;
@@ -116,7 +120,21 @@ irc_info_info_irc_is_nick_cb (const void *pointer, void *data,
if (!arguments || !arguments[0])
return NULL;
return (irc_nick_is_nick (arguments)) ? strdup ("1") : NULL;
ptr_server = NULL;
pos_nick = arguments;
pos_comma = strchr (arguments, ',');
if (pos_comma)
{
pos_nick = pos_comma + 1;
server = weechat_strndup (arguments, pos_comma - arguments);
if (server)
{
ptr_server = irc_server_search (server);
free (server);
}
}
return (irc_nick_is_nick (ptr_server, pos_nick)) ? strdup ("1") : NULL;
}
/*
@@ -1072,7 +1090,7 @@ irc_info_init ()
weechat_hook_info (
"irc_is_nick",
N_("1 if string is a valid IRC nick name"),
N_("nickname"),
N_("server,nickname (server is optional)"),
&irc_info_info_irc_is_nick_cb, NULL, NULL);
weechat_hook_info (
"irc_nick",
+44 -12
View File
@@ -62,31 +62,63 @@ irc_nick_valid (struct t_irc_channel *channel, struct t_irc_nick *nick)
}
/*
* Checks if string is a valid nick string (RFC 1459).
* Checks if string is a valid nick string, using server UTF8MAPPING.
*
* Returns:
* 1: string is a valid nick
* 0: string is not a valid nick
* 1: string is a valid nick on this server
* 0: string is not a valid nick on this server
*/
int
irc_nick_is_nick (const char *string)
irc_nick_is_nick (struct t_irc_server *server, const char *string)
{
const char *ptr;
const char *ptr_string;
int utf8mapping;
if (!string || !string[0])
return 0;
/* first char must not be a number or hyphen */
ptr = string;
if (strchr ("0123456789-", *ptr))
return 0;
utf8mapping = (server) ? server->utf8mapping : IRC_SERVER_UTF8MAPPING_NONE;
while (ptr && ptr[0])
/* check length of nick in bytes (if we have a limit in the server) */
if (server && (server->nick_max_length > 0)
&& (int)strlen (string) > server->nick_max_length)
{
if (!strchr (IRC_NICK_VALID_CHARS, *ptr))
/* nick is too long */
return 0;
}
/* check if nick is UTF-8 valid */
if ((utf8mapping == IRC_SERVER_UTF8MAPPING_RFC8265)
&& !weechat_utf8_is_valid (string, -1, NULL))
{
/* invalid UTF-8 */
return 0;
}
/* check the first char in the nick */
if ((utf8mapping == IRC_SERVER_UTF8MAPPING_NONE)
&& strchr ("0123456789-", string[0]))
{
/* first char is invalid */
return 0;
}
/* check if there are forbidden chars in nick */
ptr_string = string;
while (ptr_string && ptr_string[0])
{
if ((utf8mapping == IRC_SERVER_UTF8MAPPING_NONE)
&& !strchr (IRC_NICK_VALID_CHARS, ptr_string[0]))
{
return 0;
ptr++;
}
if ((utf8mapping == IRC_SERVER_UTF8MAPPING_RFC8265)
&& strchr (IRC_NICK_INVALID_CHARS, ptr_string[0]))
{
return 0;
}
ptr_string = weechat_utf8_next_char (ptr_string);
}
return 1;
+2 -1
View File
@@ -22,6 +22,7 @@
#define IRC_NICK_VALID_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHI" \
"JKLMNOPQRSTUVWXYZ0123456789-[]\\`_^{|}"
#define IRC_NICK_INVALID_CHARS " ,:\n\r*?.!@"
/* nicklist group for nicks without prefix is "999|..." */
#define IRC_NICK_GROUP_OTHER_NUMBER 999
@@ -47,7 +48,7 @@ struct t_irc_nick
extern int irc_nick_valid (struct t_irc_channel *channel,
struct t_irc_nick *nick);
extern int irc_nick_is_nick (const char *string);
extern int irc_nick_is_nick (struct t_irc_server *server, const char *string);
extern char *irc_nick_find_color (const char *nickname);
extern char *irc_nick_find_color_name (const char *nickname);
extern void irc_nick_set_host (struct t_irc_nick *nick, const char *host);
+16 -1
View File
@@ -3096,7 +3096,7 @@ IRC_PROTOCOL_CALLBACK(001)
IRC_PROTOCOL_CALLBACK(005)
{
char *pos, *pos2, *pos_start, *error, *isupport2;
int length_isupport, length, casemapping;
int length_isupport, length, casemapping, utf8mapping;
long value;
IRC_PROTOCOL_MIN_ARGS(4);
@@ -3181,6 +3181,21 @@ IRC_PROTOCOL_CALLBACK(005)
pos2[0] = ' ';
}
/* save utf8mapping */
pos = strstr (argv_eol[3], "UTF8MAPPING=");
if (pos)
{
pos += 12;
pos2 = strchr (pos, ' ');
if (pos2)
pos2[0] = '\0';
utf8mapping = irc_server_search_utf8mapping (pos);
if (utf8mapping >= 0)
server->utf8mapping = utf8mapping;
if (pos2)
pos2[0] = ' ';
}
/* save chantypes */
pos = strstr (argv_eol[3], "CHANTYPES=");
if (pos)
+38 -4
View File
@@ -124,6 +124,9 @@ char *irc_server_options[IRC_SERVER_NUM_OPTIONS][2] =
char *irc_server_casemapping_string[IRC_SERVER_NUM_CASEMAPPING] =
{ "rfc1459", "strict-rfc1459", "ascii" };
char *irc_server_utf8mapping_string[IRC_SERVER_NUM_UTF8MAPPING] =
{ "none", "rfc8265" };
char *irc_server_prefix_modes_default = "ov";
char *irc_server_prefix_chars_default = "@+";
char *irc_server_chanmodes_default = "beI,k,l";
@@ -248,8 +251,8 @@ irc_server_search_option (const char *option_name)
/*
* Searches for a casemapping.
*
* Returns index of casemapping in array "irc_server_casemapping_string", -1 if
* not found.
* Returns index of casemapping in array "irc_server_casemapping_string",
* -1 if not found.
*/
int
@@ -267,6 +270,28 @@ irc_server_search_casemapping (const char *casemapping)
return -1;
}
/*
* Searches for a utf8mapping.
*
* Returns index of utf8mapping in array "irc_server_utf8mapping_string",
* -1 if not found.
*/
int
irc_server_search_utf8mapping (const char *utf8mapping)
{
int i;
for (i = 0; i < IRC_SERVER_NUM_UTF8MAPPING; i++)
{
if (weechat_strcasecmp (irc_server_utf8mapping_string[i], utf8mapping) == 0)
return i;
}
/* utf8mapping not found */
return -1;
}
/*
* Compares two strings on server (case insensitive, depends on casemapping).
*
@@ -302,8 +327,8 @@ irc_server_strcasecmp (struct t_irc_server *server,
}
/*
* Compares two strings on server (case insensitive, depends on casemapping) for
* max chars.
* Compares two strings on server (case insensitive, depends on casemapping)
* for max chars.
*
* Returns:
* < 0: string1 < string2
@@ -1415,6 +1440,7 @@ irc_server_alloc (const char *name)
new_server->user_max_length = 0;
new_server->host_max_length = 0;
new_server->casemapping = IRC_SERVER_CASEMAPPING_RFC1459;
new_server->utf8mapping = IRC_SERVER_UTF8MAPPING_NONE;
new_server->chantypes = NULL;
new_server->chanmodes = NULL;
new_server->monitor = 0;
@@ -5743,6 +5769,7 @@ irc_server_hdata_server_cb (const void *pointer, void *data,
WEECHAT_HDATA_VAR(struct t_irc_server, user_max_length, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, host_max_length, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, casemapping, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, utf8mapping, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, chantypes, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, chanmodes, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, monitor, INTEGER, 0, NULL, NULL);
@@ -5990,6 +6017,10 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "casemapping_string", irc_server_casemapping_string[server->casemapping]))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "utf8mapping", server->utf8mapping))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "utf8mapping_string", irc_server_utf8mapping_string[server->utf8mapping]))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "chantypes", server->chantypes))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "chanmodes", server->chanmodes))
@@ -6378,6 +6409,9 @@ irc_server_print_log ()
weechat_log_printf (" casemapping. . . . . : %d (%s)",
ptr_server->casemapping,
irc_server_casemapping_string[ptr_server->casemapping]);
weechat_log_printf (" utf8mapping. . . . . : %d (%s)",
ptr_server->utf8mapping,
irc_server_utf8mapping_string[ptr_server->utf8mapping]);
weechat_log_printf (" chantypes. . . . . . : '%s'", ptr_server->chantypes);
weechat_log_printf (" chanmodes. . . . . . : '%s'", ptr_server->chanmodes);
weechat_log_printf (" monitor. . . . . . . : %d", ptr_server->monitor);
+11
View File
@@ -142,6 +142,15 @@ enum t_irc_server_casemapping
IRC_SERVER_NUM_CASEMAPPING,
};
/* utf8mapping (string comparisons for nicks/channels) */
enum t_irc_server_utf8mapping
{
IRC_SERVER_UTF8MAPPING_NONE = 0,
IRC_SERVER_UTF8MAPPING_RFC8265,
/* number of utf8mapping */
IRC_SERVER_NUM_UTF8MAPPING,
};
/* output queue of messages to server (for sending slowly to server) */
struct t_irc_outqueue
@@ -210,6 +219,7 @@ struct t_irc_server
int user_max_length; /* max length of user (from msg 005) */
int host_max_length; /* max length of host (from msg 005) */
int casemapping; /* casemapping from msg 005 */
int utf8mapping; /* utf8mapping from msg 005 */
char *chantypes; /* chantypes from msg 005 (eg "&#") */
char *chanmodes; /* chanmodes from msg 005 */
/* (eg "beI,k,l,imnpstaqr") */
@@ -284,6 +294,7 @@ extern struct t_irc_server *irc_server_search (const char *server_name);
extern struct t_irc_server *irc_server_casesearch (const char *server_name);
extern int irc_server_search_option (const char *option_name);
extern int irc_server_search_casemapping (const char *casemapping);
extern int irc_server_search_utf8mapping (const char *utf8mapping);
extern int irc_server_strcasecmp (struct t_irc_server *server,
const char *string1, const char *string2);
extern int irc_server_strncasecmp (struct t_irc_server *server,
+20 -3
View File
@@ -339,7 +339,7 @@ irc_upgrade_read_cb (const void *pointer, void *data,
int object_id,
struct t_infolist *infolist)
{
int flags, sock, size, i, index, nicks_count, num_items;
int flags, sock, size, i, index, nicks_count, num_items, utf8mapping;
long number;
time_t join_time;
char *buf, option_name[64], **nicks, *nick_join, *pos, *error;
@@ -479,7 +479,7 @@ irc_upgrade_read_cb (const void *pointer, void *data,
irc_upgrade_current_server->prefix_chars = strdup (str);
}
irc_upgrade_current_server->nick_max_length = weechat_infolist_integer (infolist, "nick_max_length");
/* "user_max_length" is new in WeeChat 2.6 */
/* "user_max_length" is new in WeeChat 2.6 */
if (weechat_infolist_search_var (infolist, "user_max_length"))
{
irc_upgrade_current_server->user_max_length = weechat_infolist_integer (infolist, "user_max_length");
@@ -497,7 +497,7 @@ irc_upgrade_read_cb (const void *pointer, void *data,
irc_upgrade_current_server->user_max_length = (int)number;
}
}
/* "host_max_length" is new in WeeChat 2.6 */
/* "host_max_length" is new in WeeChat 2.6 */
if (weechat_infolist_search_var (infolist, "host_max_length"))
{
irc_upgrade_current_server->host_max_length = weechat_infolist_integer (infolist, "host_max_length");
@@ -516,6 +516,23 @@ irc_upgrade_read_cb (const void *pointer, void *data,
}
}
irc_upgrade_current_server->casemapping = weechat_infolist_integer (infolist, "casemapping");
/* "utf8mapping" is new in WeeChat 2.9 */
if (weechat_infolist_search_var (infolist, "utf8mapping"))
{
irc_upgrade_current_server->utf8mapping = weechat_infolist_integer (infolist, "utf8mapping");
}
else
{
/* WeeChat <= 2.8 */
str = irc_server_get_isupport_value (irc_upgrade_current_server,
"UTF8MAPPING");
if (str)
{
utf8mapping = irc_server_search_utf8mapping (str);
if (utf8mapping >= 0)
irc_upgrade_current_server->utf8mapping = utf8mapping;
}
}
str = weechat_infolist_string (infolist, "chantypes");
if (str)
irc_upgrade_current_server->chantypes = strdup (str);