aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/misc.c9
-rw-r--r--lib/misc.h1
-rw-r--r--nick.c12
3 files changed, 18 insertions, 4 deletions
diff --git a/lib/misc.c b/lib/misc.c
index 02b1814c..6fedb48f 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -779,3 +779,12 @@ char *get_rfc822_header( const char *text, const char *header, int len )
return NULL;
}
+
+/* Takes a string, truncates it where it's safe, returns the new length */
+int truncate_utf8( char *string, int maxlen )
+{
+ char *end;
+ g_utf8_validate( (const gchar *) string, maxlen, (const gchar **) &end );
+ *end = '\0';
+ return end - string;
+}
diff --git a/lib/misc.h b/lib/misc.h
index d8cce32b..bf587332 100644
--- a/lib/misc.h
+++ b/lib/misc.h
@@ -149,5 +149,6 @@ G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl );
G_MODULE_EXPORT int md5_verify_password( char *password, char *hash );
G_MODULE_EXPORT char **split_command_parts( char *command, int limit );
G_MODULE_EXPORT char *get_rfc822_header( const char *text, const char *header, int len );
+G_MODULE_EXPORT int truncate_utf8( char *string, int maxlen );
#endif
diff --git a/nick.c b/nick.c
index 63140042..2c3f9a66 100644
--- a/nick.c
+++ b/nick.c
@@ -226,7 +226,7 @@ char *nick_gen( bee_user_t *bu )
if( ok && rets && *rets )
{
nick_strip( irc, rets );
- rets[MAX_NICK_LENGTH] = '\0';
+ truncate_utf8( rets, MAX_NICK_LENGTH );
return rets;
}
g_free( rets );
@@ -251,7 +251,12 @@ void nick_dedupe( bee_user_t *bu, char nick[MAX_NICK_LENGTH+1] )
}
else
{
- nick[0] ++;
+ /* We've got no more space for underscores,
+ so truncate it and replace the last three
+ chars with a random "_XX" suffix */
+ int len = truncate_utf8( nick, MAX_NICK_LENGTH - 3 );
+ nick[len] = '_';
+ g_snprintf(nick + len + 1, 3, "%2x", rand() );
}
if( inf_protection-- == 0 )
@@ -399,8 +404,7 @@ int nick_lc( irc_t *irc, char *nick )
gchar *down = g_utf8_strdown( nick, -1 );
if( strlen( down ) > strlen( nick ) )
{
- /* Well crap. Corrupt it if we have to. */
- down[strlen(nick)] = '\0';
+ truncate_utf8( down, strlen(nick) );
}
strcpy( nick, down );
g_free( down );