From 4fe7d06811a57449e23048c9321ac60a874daa7a Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Thu, 25 Feb 2016 14:59:09 -0500 Subject: [PATCH] Add support for rfc3454 casemapping Obviously this has less than ideal performance but it should at least be correct --- src/common/modes.c | 4 +++- src/common/util.c | 27 +++++++++++++++++++++++++++ src/common/util.h | 1 + 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/common/modes.c b/src/common/modes.c index c65bf279..16869406 100644 --- a/src/common/modes.c +++ b/src/common/modes.c @@ -840,7 +840,9 @@ inbound_005 (server * serv, char *word[], const message_tags_data *tags_data) } else if (strncmp (word[w], "CASEMAPPING=", 12) == 0) { if (strcmp (word[w] + 12, "ascii") == 0) /* bahamut */ - serv->p_cmp = (void *)g_ascii_strcasecmp; + serv->p_cmp = g_ascii_strcasecmp; + else if (strcmp (word[w] + 12, "rfc3454") == 0) + serv->p_cmp = rfc3454_casecmp; } else if (strncmp (word[w], "CHARSET=", 8) == 0) { if (g_ascii_strncasecmp (word[w] + 8, "UTF-8", 5) == 0) diff --git a/src/common/util.c b/src/common/util.c index 5c4eb8bf..ff886968 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1018,6 +1018,33 @@ make_ping_time (void) return (timev.tv_sec - 50000) * 1000 + timev.tv_usec/1000; } +/* + * https://tools.ietf.org/html/rfc3454 + */ +int +rfc3454_casecmp (const char *s1, const char *s2) +{ + char *s1_lower, *s2_lower, *s1_normal, *s2_normal; + int ret; + + if (strcmp (s1, s2) == 0) + return 0; /* Exact same already */ + + s1_lower = g_utf8_casefold(s1, -1); + s2_lower = g_utf8_casefold(s2, -1); + s1_normal = g_utf8_normalize(s1_lower, -1, G_NORMALIZE_NFKC); + s2_normal = g_utf8_normalize(s2_lower, -1, G_NORMALIZE_NFKC); + + ret = strcmp (s1_normal, s2_normal); + + g_free (s1_normal); + g_free (s2_normal); + g_free (s1_lower); + g_free (s2_lower); + + return ret; +} + /************************************************************************ * This technique was borrowed in part from the source code to diff --git a/src/common/util.h b/src/common/util.h index ba318585..505fd265 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -44,6 +44,7 @@ char *file_part (char *file); void for_files (char *dirname, char *mask, void callback (char *file)); int rfc_casecmp (const char *, const char *); int rfc_ncasecmp (char *, char *, int); +int rfc3454_casecmp (const char *s1, const char *s2) G_GNUC_PURE; int buf_get_line (char *, char **, int *, int len); char *nocasestrstr (const char *text, const char *tofind); char *country (char *);