aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2015-06-11 21:00:00 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2015-06-11 21:00:00 +0200
commit8a28bfa3d1de71437fb1eca7b65b506414b18b76 (patch)
treef4b970308f103aaaf9f125d59670ad47710f17bd
parent99b92fdd6e181aac2bd8fd021cd2718978126f49 (diff)
downloadliberty-8a28bfa3d1de71437fb1eca7b65b506414b18b76.tar.gz
liberty-8a28bfa3d1de71437fb1eca7b65b506414b18b76.tar.xz
liberty-8a28bfa3d1de71437fb1eca7b65b506414b18b76.zip
IRC: properly unescape message tags
-rw-r--r--liberty-proto.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/liberty-proto.c b/liberty-proto.c
index f4934da..c2ea64c 100644
--- a/liberty-proto.c
+++ b/liberty-proto.c
@@ -32,6 +32,35 @@ struct irc_message
struct str_vector params; ///< Command parameters
};
+static char *
+irc_unescape_message_tag (const char *value)
+{
+ struct str s;
+ str_init (&s);
+
+ bool escape = false;
+ for (const char *p = value; *p; p++)
+ {
+ if (escape)
+ {
+ switch (*p)
+ {
+ case ':': str_append_c (&s, ';'); break;
+ case 's': str_append_c (&s, ' '); break;
+ case 'r': str_append_c (&s, '\r'); break;
+ case 'n': str_append_c (&s, '\n'); break;
+ default: str_append_c (&s, *p);
+ }
+ escape = false;
+ }
+ else if (*p == '\\')
+ escape = true;
+ else
+ str_append_c (&s, *p);
+ }
+ return str_steal (&s);
+}
+
static void
irc_parse_message_tags (const char *tags, struct str_map *out)
{
@@ -45,7 +74,7 @@ irc_parse_message_tags (const char *tags, struct str_map *out)
if (equal_sign)
{
*equal_sign = '\0';
- str_map_set (out, key, xstrdup (equal_sign + 1));
+ str_map_set (out, key, irc_unescape_message_tag (equal_sign + 1));
}
else
str_map_set (out, key, xstrdup (""));