ext/rinku/autolink.c in rinku-1.0.0 vs ext/rinku/autolink.c in rinku-1.1.0
- old
+ new
@@ -45,11 +45,18 @@
static size_t
autolink_delim(char *data, size_t link_end, size_t offset, size_t size)
{
char cclose, copen = 0;
+ size_t i;
+ for (i = 0; i < link_end; ++i)
+ if (data[i] == '<') {
+ link_end = i;
+ break;
+ }
+
while (link_end > 0) {
if (strchr("?!.,", data[link_end - 1]) != NULL)
link_end--;
else if (data[link_end - 1] == ';') {
@@ -61,15 +68,10 @@
if (new_end < link_end - 2 && data[new_end] == '&')
link_end = new_end;
else
link_end--;
}
-
- else if (data[link_end - 1] == '>') {
- while (link_end > 0 && data[link_end] != '<')
- link_end--;
- }
else break;
}
if (link_end == 0)
return 0;
@@ -123,33 +125,48 @@
}
return link_end;
}
+static size_t
+check_domain(char *data, size_t size)
+{
+ size_t i, np = 0;
+
+ if (!isalnum(data[0]))
+ return 0;
+
+ for (i = 1; i < size - 1; ++i) {
+ if (data[i] == '.') np++;
+ else if (!isalnum(data[i])) break;
+ }
+
+ if (!isalnum(data[i - 1]) || np == 0)
+ return 0;
+
+ return i;
+}
+
size_t
ups_autolink__www(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size)
{
size_t link_end;
- int np = 0;
if (offset > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
return 0;
if (size < 4 || memcmp(data, "www.", STRLEN("www.")) != 0)
return 0;
- link_end = 0;
- while (link_end < size && !isspace(data[link_end])) {
- if (data[link_end] == '.')
- np++;
+ link_end = check_domain(data, size);
- link_end++;
- }
-
- if (np < 2)
+ if (link_end == 0)
return 0;
+ while (link_end < size && !isspace(data[link_end]))
+ link_end++;
+
link_end = autolink_delim(data, link_end, offset, size);
if (link_end == 0)
return 0;
@@ -209,21 +226,26 @@
}
size_t
ups_autolink__url(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size)
{
- size_t link_end, rewind = 0;
+ size_t link_end, rewind = 0, domain_len;
if (size < 4 || data[1] != '/' || data[2] != '/')
return 0;
while (rewind < offset && isalpha(data[-rewind - 1]))
rewind++;
if (!is_safe_link(data - rewind, size + rewind))
return 0;
+ link_end = STRLEN("://");
- link_end = 0;
+ domain_len = check_domain(data + link_end, size - link_end);
+ if (domain_len == 0)
+ return 0;
+
+ link_end += domain_len;
while (link_end < size && !isspace(data[link_end]))
link_end++;
link_end = autolink_delim(data, link_end, offset, size);