diff options
-rw-r--r-- | lib/misc.c | 9 | ||||
-rw-r--r-- | lib/misc.h | 1 | ||||
-rw-r--r-- | nick.c | 12 |
3 files changed, 18 insertions, 4 deletions
@@ -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; +} @@ -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 @@ -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 ); |