irc: escape/unescape IRC message tags values (issue #1654)
Spec: https://ircv3.net/specs/extensions/message-tags#escaping-values
This commit is contained in:
parent
b3b4ef648b
commit
23c46c3f2b
@ -31,6 +31,7 @@ New features::
|
||||
Bug fixes::
|
||||
|
||||
* api: fix function string_match with joker in the string if multiple words matched in input string
|
||||
* irc: escape/unescape IRC message tags values (issue #1654)
|
||||
* irc: set notify level to "private" for received WALLOPS
|
||||
|
||||
Documentation::
|
||||
|
@ -294,6 +294,7 @@ WeeChat "core" is located in following directories:
|
||||
| irc-redirect.c | Redirection of IRC command output.
|
||||
| irc-sasl.c | SASL authentication with IRC server.
|
||||
| irc-server.c | I/O communication with IRC server.
|
||||
| irc-tag.c | Functions to manipulate IRC message tags.
|
||||
| irc-upgrade.c | Save/restore of IRC data when upgrading WeeChat.
|
||||
| javascript/ | JavaScript plugin.
|
||||
| weechat-js.cpp | Main JavaScript functions (load/unload scripts, execute JavaScript code).
|
||||
|
@ -11837,6 +11837,20 @@ List of modifiers defined by WeeChat and plugins that can be used:
|
||||
Message displayed after `/msg` sent to nickserv. |
|
||||
Message with hidden password.
|
||||
|
||||
| [[hook_modifier_irc_tag_escape_value]] irc_tag_escape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Any string. |
|
||||
String with IRC tag value escaped,
|
||||
see: https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
| [[hook_modifier_irc_tag_unescape_value]] irc_tag_unescape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Any string. |
|
||||
String with IRC tag value unescaped,
|
||||
see: https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
| [[hook_modifier_color_decode_ansi]] color_decode_ansi +
|
||||
_(WeeChat ≥ 1.0)_ |
|
||||
"1" to keep colors, "0" to remove colors |
|
||||
|
@ -296,6 +296,7 @@ Le cœur de WeeChat est situé dans les répertoires suivants :
|
||||
| irc-redirect.c | Redirection de la sortie des commandes IRC.
|
||||
| irc-sasl.c | Authentification SASL avec le serveur IRC.
|
||||
| irc-server.c | Communication avec le serveur IRC.
|
||||
| irc-tag.c | Fonctions pour manipuler les étiquettes de message IRC.
|
||||
| irc-upgrade.c | Sauvegarde/restauration des données IRC lors de la mise à jour de WeeChat.
|
||||
| javascript/ | Extension JavaScript.
|
||||
| weechat-js.cpp | Fonctions principales pour JavaScript (chargement/déchargement des scripts, exécution de code JavaScript).
|
||||
|
@ -12083,6 +12083,20 @@ utilisés :
|
||||
Message affiché après `msg` envoyé à nickserv. |
|
||||
Message avec le mot de passe caché.
|
||||
|
||||
| [[hook_modifier_irc_tag_escape_value]] irc_tag_escape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Toute chaîne. |
|
||||
Chaîne avec la valeur de l'étiquette IRC échappée,
|
||||
voir : https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
| [[hook_modifier_irc_tag_unescape_value]] irc_tag_unescape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Toute chaîne. |
|
||||
Chaîne avec la valeur de l'étiquette IRC sans échappements,
|
||||
voir : https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
| [[hook_modifier_color_decode_ansi]] color_decode_ansi +
|
||||
_(WeeChat ≥ 1.0)_ |
|
||||
"1" pour garder les couleurs, "0" pour les supprimer |
|
||||
|
@ -12303,6 +12303,22 @@ List of modifiers defined by WeeChat and plugins that can be used:
|
||||
Message displayed after `/msg` sent to nickserv. |
|
||||
Message with hidden password.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| [[hook_modifier_irc_tag_escape_value]] irc_tag_escape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Any string. |
|
||||
String with IRC tag value escaped,
|
||||
see: https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| [[hook_modifier_irc_tag_unescape_value]] irc_tag_unescape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Any string. |
|
||||
String with IRC tag value unescaped,
|
||||
see: https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| [[hook_modifier_color_decode_ansi]] color_decode_ansi +
|
||||
_(WeeChat ≥ 1.0)_ |
|
||||
|
@ -305,6 +305,8 @@ WeeChat "core" は以下のディレクトリに配置されています:
|
||||
| irc-redirect.c | IRC コマンド出力のリダイレクト
|
||||
| irc-sasl.c | IRC サーバに対する SASL 認証
|
||||
| irc-server.c | IRC サーバとの入出力通信
|
||||
// TRANSLATION MISSING
|
||||
| irc-tag.c | Functions to manipulate IRC message tags.
|
||||
| irc-upgrade.c | WeeChat をアップグレードする際の IRC データの保存およびロード
|
||||
| javascript/ | JavaScript プラグイン
|
||||
| weechat-js.cpp | JavaScript の主要関数 (スクリプトのロード/アンロード、JavaScript コードの実行)
|
||||
|
@ -11859,6 +11859,22 @@ WeeChat とプラグインが定義する修飾子のリスト:
|
||||
`/msg` をサーバに送信した後に表示されるメッセージ |
|
||||
パスワードを隠したメッセージ
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| [[hook_modifier_irc_tag_escape_value]] irc_tag_escape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Any string. |
|
||||
String with IRC tag value escaped,
|
||||
see: https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| [[hook_modifier_irc_tag_unescape_value]] irc_tag_unescape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Any string. |
|
||||
String with IRC tag value unescaped,
|
||||
see: https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
| [[hook_modifier_color_decode_ansi]] color_decode_ansi +
|
||||
_(WeeChat バージョン 1.0 以上で利用可)_ |
|
||||
色を保持する場合は "1"、削除する場合は "0" |
|
||||
|
@ -290,6 +290,8 @@ WeeChat „језгро” се налази у следећим директо
|
||||
| irc-redirect.c | Преусмеравање излаза IRC команде.
|
||||
| irc-sasl.c | SASL аутентификација са IRC сервером.
|
||||
| irc-server.c | У/И комуникација са IRC сервером.
|
||||
// TRANSLATION MISSING
|
||||
| irc-tag.c | Functions to manipulate IRC message tags.
|
||||
| irc-upgrade.c | Чување/обнављање IRC података када се ажурира програм WeeChat.
|
||||
| javascript/ | JavaScript додатак.
|
||||
| weechat-js.cpp | Главне JavaScript функције (учитавање/уклањање скрипти, извршавање JavaScript кода).
|
||||
|
@ -11405,6 +11405,22 @@ char *weechat_hook_modifier_exec (const char *modifier,
|
||||
Порука која се приказује након што се `/msg` пошаље nickserv боту. |
|
||||
Порука са скривеном лозинком.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| [[hook_modifier_irc_tag_escape_value]] irc_tag_escape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Any string. |
|
||||
String with IRC tag value escaped,
|
||||
see: https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
// TRANSLATION MISSING
|
||||
| [[hook_modifier_irc_tag_unescape_value]] irc_tag_unescape_value +
|
||||
_(WeeChat ≥ 3.3)_ |
|
||||
- |
|
||||
Any string. |
|
||||
String with IRC tag value unescaped,
|
||||
see: https://ircv3.net/specs/extensions/message-tags#escaping-values.
|
||||
|
||||
| [[hook_modifier_color_decode_ansi]] color_decode_ansi +
|
||||
_(WeeChat ≥ 1.0)_ |
|
||||
"1" да се боје задрже, "0" да се боје уклоне |
|
||||
|
@ -257,6 +257,10 @@
|
||||
./src/plugins/irc/irc-sasl.h
|
||||
./src/plugins/irc/irc-server.c
|
||||
./src/plugins/irc/irc-server.h
|
||||
./src/plugins/irc/irc-tag.c
|
||||
./src/plugins/irc/irc-tag.h
|
||||
./src/plugins/irc/irc-upgrade.c
|
||||
./src/plugins/irc/irc-upgrade.h
|
||||
./src/plugins/javascript/weechat-js-api.cpp
|
||||
./src/plugins/javascript/weechat-js-api.h
|
||||
./src/plugins/javascript/weechat-js-v8.cpp
|
||||
|
@ -258,6 +258,10 @@ SET(WEECHAT_SOURCES
|
||||
./src/plugins/irc/irc-sasl.h
|
||||
./src/plugins/irc/irc-server.c
|
||||
./src/plugins/irc/irc-server.h
|
||||
./src/plugins/irc/irc-tag.c
|
||||
./src/plugins/irc/irc-tag.h
|
||||
./src/plugins/irc/irc-upgrade.c
|
||||
./src/plugins/irc/irc-upgrade.h
|
||||
./src/plugins/javascript/weechat-js-api.cpp
|
||||
./src/plugins/javascript/weechat-js-api.h
|
||||
./src/plugins/javascript/weechat-js-v8.cpp
|
||||
|
@ -42,6 +42,7 @@ add_library(irc MODULE
|
||||
irc-redirect.c irc-redirect.h
|
||||
irc-sasl.c irc-sasl.h
|
||||
irc-server.c irc-server.h
|
||||
irc-tag.c irc-tag.h
|
||||
irc-upgrade.c irc-upgrade.h
|
||||
)
|
||||
set_target_properties(irc PROPERTIES PREFIX "")
|
||||
|
@ -71,6 +71,8 @@ irc_la_SOURCES = irc.c \
|
||||
irc-sasl.h \
|
||||
irc-server.c \
|
||||
irc-server.h \
|
||||
irc-tag.c \
|
||||
irc-tag.h \
|
||||
irc-upgrade.c \
|
||||
irc-upgrade.h
|
||||
|
||||
|
@ -53,9 +53,10 @@
|
||||
#include "irc-modelist.h"
|
||||
#include "irc-msgbuffer.h"
|
||||
#include "irc-nick.h"
|
||||
#include "irc-notify.h"
|
||||
#include "irc-sasl.h"
|
||||
#include "irc-server.h"
|
||||
#include "irc-notify.h"
|
||||
#include "irc-tag.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -199,66 +200,6 @@ irc_protocol_nick_address (struct t_irc_server *server,
|
||||
return string;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns hashtable with tags for an IRC message.
|
||||
*
|
||||
* Example:
|
||||
* if tags == "aaa=bbb;ccc;example.com/ddd=eee",
|
||||
* hashtable will have following keys/values:
|
||||
* "aaa" => "bbb"
|
||||
* "ccc" => NULL
|
||||
* "example.com/ddd" => "eee"
|
||||
*/
|
||||
|
||||
struct t_hashtable *
|
||||
irc_protocol_get_message_tags (const char *tags)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
char **items, *pos, *key;
|
||||
int num_items, i;
|
||||
|
||||
if (!tags || !tags[0])
|
||||
return NULL;
|
||||
|
||||
hashtable = weechat_hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL, NULL);
|
||||
if (!hashtable)
|
||||
return NULL;
|
||||
|
||||
items = weechat_string_split (tags, ";", NULL,
|
||||
WEECHAT_STRING_SPLIT_STRIP_LEFT
|
||||
| WEECHAT_STRING_SPLIT_STRIP_RIGHT
|
||||
| WEECHAT_STRING_SPLIT_COLLAPSE_SEPS,
|
||||
0, &num_items);
|
||||
if (items)
|
||||
{
|
||||
for (i = 0; i < num_items; i++)
|
||||
{
|
||||
pos = strchr (items[i], '=');
|
||||
if (pos)
|
||||
{
|
||||
/* format: "tag=value" */
|
||||
key = weechat_strndup (items[i], pos - items[i]);
|
||||
if (key)
|
||||
{
|
||||
weechat_hashtable_set (hashtable, key, pos + 1);
|
||||
free (key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* format: "tag" */
|
||||
weechat_hashtable_set (hashtable, items[i], NULL);
|
||||
}
|
||||
}
|
||||
weechat_string_free_split (items);
|
||||
}
|
||||
|
||||
return hashtable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses date/time received in a "time" tag.
|
||||
*
|
||||
@ -6883,7 +6824,7 @@ irc_protocol_recv_command (struct t_irc_server *server,
|
||||
pos_space - (irc_message + 1));
|
||||
if (tags)
|
||||
{
|
||||
hash_tags = irc_protocol_get_message_tags (tags);
|
||||
hash_tags = irc_tag_parse (tags);
|
||||
if (hash_tags)
|
||||
{
|
||||
date = irc_protocol_parse_time (
|
||||
|
280
src/plugins/irc/irc-tag.c
Normal file
280
src/plugins/irc/irc-tag.c
Normal file
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* irc-tag.c - functions for IRC message tags
|
||||
*
|
||||
* Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "irc.h"
|
||||
#include "irc-tag.h"
|
||||
|
||||
|
||||
/*
|
||||
* Escapes a tag value, the following sequences are replaced:
|
||||
*
|
||||
* character | escaped value
|
||||
* ---------------+-------------------------
|
||||
* ; (semicolon) | \: (backslash and colon)
|
||||
* SPACE | \s
|
||||
* \ | \\
|
||||
* CR | \r
|
||||
* LF | \n
|
||||
* all others | the character itself
|
||||
*
|
||||
* See: https://ircv3.net/specs/extensions/message-tags#escaping-values
|
||||
*
|
||||
* Note: result must be freed after use.
|
||||
*/
|
||||
|
||||
char *
|
||||
irc_tag_escape_value (const char *string)
|
||||
{
|
||||
char **out, *result;
|
||||
unsigned char *ptr_string;
|
||||
int length;
|
||||
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
length = strlen (string);
|
||||
out = weechat_string_dyn_alloc (length + (length / 2) + 1);
|
||||
if (!out)
|
||||
return NULL;
|
||||
|
||||
ptr_string = (unsigned char *)string;
|
||||
while (ptr_string && ptr_string[0])
|
||||
{
|
||||
switch (ptr_string[0])
|
||||
{
|
||||
case ';':
|
||||
weechat_string_dyn_concat (out, "\\:", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
case ' ':
|
||||
weechat_string_dyn_concat (out, "\\s", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
case '\\':
|
||||
weechat_string_dyn_concat (out, "\\\\", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
case '\r':
|
||||
weechat_string_dyn_concat (out, "\\r", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
case '\n':
|
||||
weechat_string_dyn_concat (out, "\\n", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
default:
|
||||
length = weechat_utf8_char_size ((char *)ptr_string);
|
||||
if (length == 0)
|
||||
length = 1;
|
||||
weechat_string_dyn_concat (out,
|
||||
(const char *)ptr_string,
|
||||
length);
|
||||
ptr_string += length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result = *out;
|
||||
weechat_string_dyn_free (out, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unescapes a tag value.
|
||||
*
|
||||
* See: https://ircv3.net/specs/extensions/message-tags#escaping-values
|
||||
*
|
||||
* Note: result must be freed after use.
|
||||
*/
|
||||
|
||||
char *
|
||||
irc_tag_unescape_value (const char *string)
|
||||
{
|
||||
char **out, *result;
|
||||
unsigned char *ptr_string;
|
||||
int length;
|
||||
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
length = strlen (string);
|
||||
out = weechat_string_dyn_alloc (length + (length / 2) + 1);
|
||||
if (!out)
|
||||
return NULL;
|
||||
|
||||
ptr_string = (unsigned char *)string;
|
||||
while (ptr_string && ptr_string[0])
|
||||
{
|
||||
switch (ptr_string[0])
|
||||
{
|
||||
case '\\':
|
||||
ptr_string++;
|
||||
switch (ptr_string[0])
|
||||
{
|
||||
case ':':
|
||||
weechat_string_dyn_concat (out, ";", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
case 's':
|
||||
weechat_string_dyn_concat (out, " ", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
case '\\':
|
||||
weechat_string_dyn_concat (out, "\\", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
case 'r':
|
||||
weechat_string_dyn_concat (out, "\r", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
case 'n':
|
||||
weechat_string_dyn_concat (out, "\n", -1);
|
||||
ptr_string++;
|
||||
break;
|
||||
default:
|
||||
if (ptr_string[0])
|
||||
{
|
||||
length = weechat_utf8_char_size ((char *)ptr_string);
|
||||
if (length == 0)
|
||||
length = 1;
|
||||
weechat_string_dyn_concat (out,
|
||||
(const char *)ptr_string,
|
||||
length);
|
||||
ptr_string += length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
length = weechat_utf8_char_size ((char *)ptr_string);
|
||||
if (length == 0)
|
||||
length = 1;
|
||||
weechat_string_dyn_concat (out,
|
||||
(const char *)ptr_string,
|
||||
length);
|
||||
ptr_string += length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result = *out;
|
||||
weechat_string_dyn_free (out, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for modifiers "irc_tag_escape_value" and "irc_tag_unescape_value".
|
||||
*
|
||||
* These modifiers can be used by other plugins to escape/unescape IRC message
|
||||
* tags.
|
||||
*/
|
||||
|
||||
char *
|
||||
irc_tag_modifier_cb (const void *pointer, void *data,
|
||||
const char *modifier, const char *modifier_data,
|
||||
const char *string)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) pointer;
|
||||
(void) data;
|
||||
(void) modifier_data;
|
||||
|
||||
if (strcmp (modifier, "irc_tag_escape_value") == 0)
|
||||
return irc_tag_escape_value (string);
|
||||
|
||||
if (strcmp (modifier, "irc_tag_unescape_value") == 0)
|
||||
return irc_tag_unescape_value (string);
|
||||
|
||||
/* unknown modifier */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses tags received in an IRC message.
|
||||
* Returns a hashtable with tags and their unescaped values.
|
||||
*
|
||||
* Example:
|
||||
* if tags == "aaa=bbb;ccc;example.com/ddd=eee",
|
||||
* hashtable will have following keys/values:
|
||||
* "aaa" => "bbb"
|
||||
* "ccc" => NULL
|
||||
* "example.com/ddd" => "eee"
|
||||
*/
|
||||
|
||||
struct t_hashtable *
|
||||
irc_tag_parse (const char *tags)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
char **items, *pos, *key, *unescaped;
|
||||
int num_items, i;
|
||||
|
||||
if (!tags || !tags[0])
|
||||
return NULL;
|
||||
|
||||
hashtable = weechat_hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL, NULL);
|
||||
if (!hashtable)
|
||||
return NULL;
|
||||
|
||||
items = weechat_string_split (tags, ";", NULL,
|
||||
WEECHAT_STRING_SPLIT_STRIP_LEFT
|
||||
| WEECHAT_STRING_SPLIT_STRIP_RIGHT
|
||||
| WEECHAT_STRING_SPLIT_COLLAPSE_SEPS,
|
||||
0, &num_items);
|
||||
if (items)
|
||||
{
|
||||
for (i = 0; i < num_items; i++)
|
||||
{
|
||||
pos = strchr (items[i], '=');
|
||||
if (pos)
|
||||
{
|
||||
/* format: "tag=value" */
|
||||
key = weechat_strndup (items[i], pos - items[i]);
|
||||
if (key)
|
||||
{
|
||||
unescaped = irc_tag_unescape_value (pos + 1);
|
||||
weechat_hashtable_set (hashtable, key, unescaped);
|
||||
if (unescaped)
|
||||
free (unescaped);
|
||||
free (key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* format: "tag" */
|
||||
weechat_hashtable_set (hashtable, items[i], NULL);
|
||||
}
|
||||
}
|
||||
weechat_string_free_split (items);
|
||||
}
|
||||
|
||||
return hashtable;
|
||||
}
|
32
src/plugins/irc/irc-tag.h
Normal file
32
src/plugins/irc/irc-tag.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WEECHAT_PLUGIN_IRC_TAG_H
|
||||
#define WEECHAT_PLUGIN_IRC_TAG_H
|
||||
|
||||
extern char *irc_tag_escape_value (const char *string);
|
||||
extern char *irc_tag_unescape_value (const char *string);
|
||||
extern char *irc_tag_modifier_cb (const void *pointer,
|
||||
void *data,
|
||||
const char *modifier,
|
||||
const char *modifier_data,
|
||||
const char *string);
|
||||
extern struct t_hashtable *irc_tag_parse (const char *tags);
|
||||
|
||||
#endif /* WEECHAT_PLUGIN_IRC_TAG_H */
|
@ -42,6 +42,7 @@
|
||||
#include "irc-raw.h"
|
||||
#include "irc-redirect.h"
|
||||
#include "irc-server.h"
|
||||
#include "irc-tag.h"
|
||||
#include "irc-upgrade.h"
|
||||
|
||||
|
||||
@ -213,6 +214,10 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
&irc_color_modifier_cb, NULL, NULL);
|
||||
weechat_hook_modifier ("irc_color_decode_ansi",
|
||||
&irc_color_modifier_cb, NULL, NULL);
|
||||
weechat_hook_modifier ("irc_tag_escape_value",
|
||||
&irc_tag_modifier_cb, NULL, NULL);
|
||||
weechat_hook_modifier ("irc_tag_unescape_value",
|
||||
&irc_tag_modifier_cb, NULL, NULL);
|
||||
|
||||
/* hook completions */
|
||||
irc_completion_init ();
|
||||
|
@ -62,6 +62,7 @@ if(ENABLE_IRC)
|
||||
unit/plugins/irc/test-irc-nick.cpp
|
||||
unit/plugins/irc/test-irc-protocol.cpp
|
||||
unit/plugins/irc/test-irc-server.cpp
|
||||
unit/plugins/irc/test-irc-tag.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -76,7 +76,8 @@ tests_irc = unit/plugins/irc/test-irc-channel.cpp \
|
||||
unit/plugins/irc/test-irc-mode.cpp \
|
||||
unit/plugins/irc/test-irc-nick.cpp \
|
||||
unit/plugins/irc/test-irc-protocol.cpp \
|
||||
unit/plugins/irc/test-irc-server.cpp
|
||||
unit/plugins/irc/test-irc-server.cpp \
|
||||
unit/plugins/irc/test-irc-tag.cpp
|
||||
endif
|
||||
|
||||
if PLUGIN_RELAY
|
||||
|
@ -42,7 +42,6 @@ extern const char *irc_protocol_nick_address (struct t_irc_server *server,
|
||||
struct t_irc_nick *nick,
|
||||
const char *nickname,
|
||||
const char *address);
|
||||
extern struct t_hashtable *irc_protocol_get_message_tags (const char *tags);
|
||||
extern char *irc_protocol_cap_to_enable (const char *capabilities,
|
||||
int sasl_requested);
|
||||
}
|
||||
@ -169,39 +168,6 @@ TEST(IrcProtocol, Tags)
|
||||
"example.com"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_protocol_get_message_tags
|
||||
*/
|
||||
|
||||
TEST(IrcProtocol, GetMessageTags)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
|
||||
POINTERS_EQUAL(NULL, irc_protocol_get_message_tags (NULL));
|
||||
POINTERS_EQUAL(NULL, irc_protocol_get_message_tags (""));
|
||||
|
||||
hashtable = irc_protocol_get_message_tags ("abc");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(1, hashtable->items_count);
|
||||
POINTERS_EQUAL(NULL, (const char *)hashtable_get (hashtable, "abc"));
|
||||
hashtable_free (hashtable);
|
||||
|
||||
hashtable = irc_protocol_get_message_tags ("abc=def");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(1, hashtable->items_count);
|
||||
STRCMP_EQUAL("def", (const char *)hashtable_get (hashtable, "abc"));
|
||||
hashtable_free (hashtable);
|
||||
|
||||
hashtable = irc_protocol_get_message_tags ("aaa=bbb;ccc;example.com/ddd=eee");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(3, hashtable->items_count);
|
||||
STRCMP_EQUAL("bbb", (const char *)hashtable_get (hashtable, "aaa"));
|
||||
POINTERS_EQUAL(NULL, (const char *)hashtable_get (hashtable, "ccc"));
|
||||
STRCMP_EQUAL("eee", (const char *)hashtable_get (hashtable, "example.com/ddd"));
|
||||
hashtable_free (hashtable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_protocol_parse_time
|
||||
|
147
tests/unit/plugins/irc/test-irc-tag.cpp
Normal file
147
tests/unit/plugins/irc/test-irc-tag.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* test-irc-tag.cpp - test IRC message tags functions
|
||||
*
|
||||
* Copyright (C) 2021 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CppUTest/TestHarness.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <stdio.h>
|
||||
#include "src/core/wee-hashtable.h"
|
||||
#include "src/core/wee-hook.h"
|
||||
#include "src/plugins/irc/irc-tag.h"
|
||||
}
|
||||
|
||||
#define WEE_CHECK_ESCAPE_VALUE(__result, __string) \
|
||||
escaped = irc_tag_escape_value (__string); \
|
||||
STRCMP_EQUAL(__result, escaped); \
|
||||
free (escaped);
|
||||
|
||||
#define WEE_CHECK_UNESCAPE_VALUE(__result, __string) \
|
||||
unescaped = irc_tag_unescape_value (__string); \
|
||||
STRCMP_EQUAL(__result, unescaped); \
|
||||
free (unescaped);
|
||||
|
||||
TEST_GROUP(IrcTag)
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_tag_escape_value
|
||||
*/
|
||||
|
||||
TEST(IrcTag, EscapeValue)
|
||||
{
|
||||
char *escaped;
|
||||
|
||||
/* NULL/empty string */
|
||||
POINTERS_EQUAL(NULL, irc_tag_escape_value (NULL));
|
||||
WEE_CHECK_ESCAPE_VALUE("", "");
|
||||
|
||||
WEE_CHECK_ESCAPE_VALUE("test", "test");
|
||||
WEE_CHECK_ESCAPE_VALUE("test\\:abc", "test;abc");
|
||||
WEE_CHECK_ESCAPE_VALUE("test\\sabc", "test abc");
|
||||
WEE_CHECK_ESCAPE_VALUE("test_\\\\_abc", "test_\\_abc");
|
||||
WEE_CHECK_ESCAPE_VALUE("test_\\r_abc", "test_\r_abc");
|
||||
WEE_CHECK_ESCAPE_VALUE("test_\\n_abc", "test_\n_abc");
|
||||
WEE_CHECK_ESCAPE_VALUE("test_\xf0\xa4\xad\xa2_abc",
|
||||
"test_\xf0\xa4\xad\xa2_abc");
|
||||
WEE_CHECK_ESCAPE_VALUE("\\:\\s\\\\\\r\\n", "; \\\r\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_tag_unescape_value
|
||||
*/
|
||||
|
||||
TEST(IrcTag, UnescapeValue)
|
||||
{
|
||||
char *unescaped;
|
||||
|
||||
/* NULL/empty string */
|
||||
POINTERS_EQUAL(NULL, irc_tag_unescape_value (NULL));
|
||||
WEE_CHECK_UNESCAPE_VALUE("", "");
|
||||
|
||||
WEE_CHECK_UNESCAPE_VALUE("test", "test");
|
||||
WEE_CHECK_UNESCAPE_VALUE("test", "test\\");
|
||||
WEE_CHECK_UNESCAPE_VALUE("test;abc", "test\\:abc");
|
||||
WEE_CHECK_UNESCAPE_VALUE("test abc", "test\\sabc");
|
||||
WEE_CHECK_UNESCAPE_VALUE("test_\\_abc", "test_\\\\_abc");
|
||||
WEE_CHECK_UNESCAPE_VALUE("test_\r_abc", "test_\\r_abc");
|
||||
WEE_CHECK_UNESCAPE_VALUE("test_\n_abc", "test_\\n_abc");
|
||||
WEE_CHECK_UNESCAPE_VALUE("test_a_abc", "test_\\a_abc");
|
||||
WEE_CHECK_UNESCAPE_VALUE("test_\xf0\xa4\xad\xa2_abc",
|
||||
"test_\\\xf0\xa4\xad\xa2_abc");
|
||||
WEE_CHECK_UNESCAPE_VALUE("; \\\r\n", "\\:\\s\\\\\\r\\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_tag_modifier_cb
|
||||
*/
|
||||
|
||||
TEST(IrcTag, ModifierCallback)
|
||||
{
|
||||
char *result;
|
||||
|
||||
/* modifier "irc_tag_escape_value" */
|
||||
result = hook_modifier_exec (NULL, "irc_tag_escape_value", NULL, "test");
|
||||
STRCMP_EQUAL("test", result);
|
||||
free (result);
|
||||
|
||||
/* modifier "irc_tag_unescape_value" */
|
||||
result = hook_modifier_exec (NULL, "irc_tag_unescape_value", NULL, "test");
|
||||
STRCMP_EQUAL("test", result);
|
||||
free (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* irc_tag_parse
|
||||
*/
|
||||
|
||||
TEST(IrcTag, Parse)
|
||||
{
|
||||
struct t_hashtable *hashtable;
|
||||
|
||||
POINTERS_EQUAL(NULL, irc_tag_parse (NULL));
|
||||
POINTERS_EQUAL(NULL, irc_tag_parse (""));
|
||||
|
||||
hashtable = irc_tag_parse ("abc");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(1, hashtable->items_count);
|
||||
POINTERS_EQUAL(NULL, (const char *)hashtable_get (hashtable, "abc"));
|
||||
hashtable_free (hashtable);
|
||||
|
||||
hashtable = irc_tag_parse ("abc=def");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(1, hashtable->items_count);
|
||||
STRCMP_EQUAL("def", (const char *)hashtable_get (hashtable, "abc"));
|
||||
hashtable_free (hashtable);
|
||||
|
||||
hashtable = irc_tag_parse ("aaa=bbb;ccc;example.com/ddd=eee");
|
||||
CHECK(hashtable);
|
||||
LONGS_EQUAL(3, hashtable->items_count);
|
||||
STRCMP_EQUAL("bbb", (const char *)hashtable_get (hashtable, "aaa"));
|
||||
POINTERS_EQUAL(NULL, (const char *)hashtable_get (hashtable, "ccc"));
|
||||
STRCMP_EQUAL("eee", (const char *)hashtable_get (hashtable, "example.com/ddd"));
|
||||
hashtable_free (hashtable);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user