Index: src/util.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/util.c,v retrieving revision 1.289 diff -u -p -r1.289 util.c --- src/util.c 19 May 2004 04:02:08 -0000 1.289 +++ src/util.c 23 May 2004 13:40:41 -0000 @@ -1518,8 +1518,12 @@ gaim_markup_linkify(const char *text) *d = '\0'; tmpurlbuf = gaim_unescape_html(url_buf); - g_string_append_printf(ret, "%s", - tmpurlbuf, url_buf); + if (gaim_email_is_valid(tmpurlbuf)) { + g_string_append_printf(ret, "%s", + tmpurlbuf, url_buf); + } else { + g_string_append(ret, url_buf); + } g_free(tmpurlbuf); c = t; @@ -2583,6 +2587,59 @@ gaim_url_encode(const char *str) return buf; } +/* Originally lifted from + * http://www.oreillynet.com/pub/a/network/excerpt/spcookbook_chap03/index3.html + * ... and slightly modified to be a bit more rfc822 compliant + * ... and modified a bit more to make domain checking rfc1035 compliant + * with the exception permitted in rfc1101 for domains to start with digit + * but not completely checking to avoid conflicts with IP addresses + */ +gboolean +gaim_email_is_valid(const char *address) +{ + const char *c, *domain; + static char *rfc822_specials = "()<>@,;:\\\"[]"; + + /* first we validate the name portion (name@domain) (rfc822)*/ + for (c = address; *c; c++) { + if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == '\"')) { + while (*++c) { + if (*c == '\\') { + if (*c++ && *c < 127 && *c != '\n' && *c != '\r') continue; + else return FALSE; + } + if (*c == '\"') break; + if (*c < ' ' || *c >= 127) return FALSE; + } + if (!*c++) return FALSE; + if (*c == '@') break; + if (*c != '.') return FALSE; + continue; + } + if (*c == '@') break; + if (*c <= ' ' || *c >= 127) return FALSE; + if (strchr(rfc822_specials, *c)) return FALSE; + } + /* strictly we should return false if (*(c - 1) == '.') too, but I think + * we should permit user.@domain type addresses - they do work :) */ + if (c == address) return FALSE; + + /* next we validate the domain portion (name@domain) (rfc1035 & rfc1011) */ + if (!*(domain = ++c)) return FALSE; + do { + if (*c == '.' && (c == domain || *(c - 1) == '.' || *(c - 1) == '-')) + return FALSE; + if (*c == '-' && *(c - 1) == '.') return FALSE; + if ((*c < '0' && *c != '-' && *c != '.') || (*c > '9' && *c < 'A') || + (*c > 'Z' && *c < 'a') || (*c > 'z')) return FALSE; + } while (*++c); + + if (*(c - 1) == '-') return FALSE; + + return ((c - domain) > 3 ? TRUE : FALSE); +} + + /************************************************************************** * UTF8 String Functions **************************************************************************/ Index: src/util.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/util.h,v retrieving revision 1.52 diff -u -p -r1.52 util.h --- src/util.h 21 May 2004 19:09:38 -0000 1.52 +++ src/util.h 23 May 2004 13:40:41 -0000 @@ -579,6 +579,15 @@ const char *gaim_url_decode(const char * */ const char *gaim_url_encode(const char *str); +/** + * Checks if the given email address is syntactically valid. + * + * @param address The email address to validate. + * + * @return True if the email address is syntactically correct. + */ +gboolean gaim_email_is_valid(const char *address); + /*@}*/ /**************************************************************************