Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix segfault with chained email addresses

  • Loading branch information...
commit dc685c15e30d9a02a0144170798538ea4754f0a6 1 parent facbe81
@vmg authored
Showing with 20 additions and 13 deletions.
  1. +10 −10 ext/rinku/autolink.c
  2. +6 −3 ext/rinku/rinku.c
  3. +4 −0 test/autolink_test.rb
View
20 ext/rinku/autolink.c
@@ -49,7 +49,7 @@ sd_autolink_issafe(const uint8_t *link, size_t link_len)
}
static size_t
-autolink_delim(uint8_t *data, size_t link_end, size_t offset, size_t size)
+autolink_delim(uint8_t *data, size_t link_end, size_t max_rewind, size_t size)
{
uint8_t cclose, copen = 0;
size_t i;
@@ -163,13 +163,13 @@ sd_autolink__www(
size_t *rewind_p,
struct buf *link,
uint8_t *data,
- size_t offset,
+ size_t max_rewind,
size_t size,
unsigned int flags)
{
size_t link_end;
- if (offset > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
+ if (max_rewind > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
return 0;
if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
@@ -183,7 +183,7 @@ sd_autolink__www(
while (link_end < size && !isspace(data[link_end]))
link_end++;
- link_end = autolink_delim(data, link_end, offset, size);
+ link_end = autolink_delim(data, link_end, max_rewind, size);
if (link_end == 0)
return 0;
@@ -199,14 +199,14 @@ sd_autolink__email(
size_t *rewind_p,
struct buf *link,
uint8_t *data,
- size_t offset,
+ size_t max_rewind,
size_t size,
unsigned int flags)
{
size_t link_end, rewind;
int nb = 0, np = 0;
- for (rewind = 0; rewind < offset; ++rewind) {
+ for (rewind = 0; rewind < max_rewind; ++rewind) {
uint8_t c = data[-rewind - 1];
if (isalnum(c))
@@ -238,7 +238,7 @@ sd_autolink__email(
if (link_end < 2 || nb != 1 || np == 0)
return 0;
- link_end = autolink_delim(data, link_end, offset, size);
+ link_end = autolink_delim(data, link_end, max_rewind, size);
if (link_end == 0)
return 0;
@@ -254,7 +254,7 @@ sd_autolink__url(
size_t *rewind_p,
struct buf *link,
uint8_t *data,
- size_t offset,
+ size_t max_rewind,
size_t size,
unsigned int flags)
{
@@ -263,7 +263,7 @@ sd_autolink__url(
if (size < 4 || data[1] != '/' || data[2] != '/')
return 0;
- while (rewind < offset && isalpha(data[-rewind - 1]))
+ while (rewind < max_rewind && isalpha(data[-rewind - 1]))
rewind++;
if (!sd_autolink_issafe(data - rewind, size + rewind))
@@ -283,7 +283,7 @@ sd_autolink__url(
while (link_end < size && !isspace(data[link_end]))
link_end++;
- link_end = autolink_delim(data, link_end, offset, size);
+ link_end = autolink_delim(data, link_end, max_rewind, size);
if (link_end == 0)
return 0;
View
9 ext/rinku/rinku.c
@@ -194,7 +194,7 @@ rinku_autolink(
void (*link_text_cb)(struct buf *ob, const struct buf *link, void *payload),
void *payload)
{
- size_t i, end;
+ size_t i, end, last_link_found = 0;
struct buf *link = bufnew(16);
char active_chars[256];
void (*link_url_cb)(struct buf *, const struct buf *, void *);
@@ -249,8 +249,11 @@ rinku_autolink(
}
link->size = 0;
+
link_end = g_callbacks[(int)action](
- &rewind, link, (uint8_t *)text + end, end, size - end, flags);
+ &rewind, link, (uint8_t *)text + end,
+ end - last_link_found,
+ size - end, flags);
/* print the link */
if (link_end > 0) {
@@ -272,7 +275,7 @@ rinku_autolink(
link_count++;
i = end + link_end;
- end = i;
+ last_link_found = end = i;
} else {
end = end + 1;
}
View
4 test/autolink_test.rb
@@ -15,6 +15,10 @@ def assert_linked(expected, url)
assert_equal expected, Rinku.auto_link(url)
end
+ def test_segfault
+ Rinku.auto_link("a+b@d.com+e@f.com", mode=:all)
+ end
+
def test_escapes_quotes
assert_linked %(<a href="http://website.com/&quot;onmouseover=document.body.style.backgroundColor=&quot;pink&quot;;//">http://website.com/"onmouseover=document.body.style.backgroundColor="pink";//</a>),
%(http://website.com/"onmouseover=document.body.style.backgroundColor="pink";//)
Please sign in to comment.
Something went wrong with that request. Please try again.