aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog7
-rw-r--r--mail/mail-format.c62
2 files changed, 55 insertions, 14 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index b78f6d01ab..d5dcd9d896 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,10 @@
+2000-04-27 Dan Winship <danw@helixcode.com>
+
+ * mail-format.c (text_to_html): Improve URL converstion code.
+ Recognize https, recognize "www\..*" without a prefixed "http://".
+ Properly escape &, <, >, etc in URL strings. Don't be fooled by
+ "mailto:", "http://", etc with no following data.
+
2000-04-26 Dan Winship <danw@helixcode.com>
* mail-format.c (text_to_html): Reorganize a bit and add a new
diff --git a/mail/mail-format.c b/mail/mail-format.c
index 033440e876..f8d9085d64 100644
--- a/mail/mail-format.c
+++ b/mail/mail-format.c
@@ -380,6 +380,31 @@ check_size (char **buffer, int *buffer_size, char *out, int len)
return out;
}
+char *
+url_extract (const char **text, gboolean check)
+{
+ const char *end = *text, *p;
+ char *out;
+
+ while (*end && !isspace (*end) && *end != '"')
+ end++;
+
+ /* Back up if we probably went too far. */
+ while (end > *text && strchr (",.!?;:>", *(end - 1)))
+ end--;
+
+ if (check) {
+ /* Make sure we weren't fooled. */
+ p = memchr (*text, ':', end - *text);
+ if (!p || end - p < 3)
+ return NULL;
+ }
+
+ out = g_strndup (*text, end - *text);
+ *text = end;
+ return out;
+}
+
/* Convert plain text into equivalent-looking valid HTML. */
static char *
text_to_html (const unsigned char *input, unsigned int flags)
@@ -399,28 +424,37 @@ text_to_html (const unsigned char *input, unsigned int flags)
while (*cur) {
if (isalpha (*cur) && (flags & TEXT_TO_HTML_CONVERT_URLS)) {
+ char *tmpurl = NULL, *refurl, *dispurl;
+
if (!strncasecmp (cur, "http://", 7) ||
+ !strncasecmp (cur, "https://", 8) ||
!strncasecmp (cur, "ftp://", 6) ||
!strncasecmp (cur, "nntp://", 7) ||
!strncasecmp (cur, "mailto:", 7) ||
!strncasecmp (cur, "news:", 5)) {
- /* Skip to end of URL. */
- end = cur;
- while (*end && !isspace (*end) && *end != '"')
- end++;
-
- /* Back up if we probably went too far. */
- while (end > cur &&
- strchr (",.!?;:>", *(end - 1)))
- end--;
+ tmpurl = url_extract (&cur, TRUE);
+ if (tmpurl) {
+ refurl = text_to_html (tmpurl, 0);
+ dispurl = g_strdup (refurl);
+ }
+ } else if (!strncasecmp (cur, "www.", 4) &&
+ isalnum (*(cur + 4))) {
+ tmpurl = url_extract (&cur, FALSE);
+ dispurl = text_to_html (tmpurl, 0);
+ refurl = g_strdup_printf ("http://%s",
+ dispurl);
+ }
+ if (tmpurl) {
out = check_size (&buffer, &buffer_size, out,
- (end - cur) * 2 + 15);
+ strlen (refurl) +
+ strlen (dispurl) + 15);
out += sprintf (out,
- "<a href=\"%.*s\">%.*s</a>",
- end - cur, cur,
- end - cur, cur);
- cur = end;
+ "<a href=\"%s\">%s</a>",
+ refurl, dispurl);
+ g_free (tmpurl);
+ g_free (refurl);
+ g_free (dispurl);
}
}