Permalink
Browse files

Avoid rewinding previous inline when auto-linking

When a bit like "_foo_1@bar.com" is processed, first the emphasis is
rendered, then the 1 is output verbatim. When the `@` is encountered,
Redcarpet tries to find the "local part" of the address and stops when
it encounters an invalid char (i.e. here the `!`).

The problem is that when it searches for the local part, Redcarpet
rewinds the characters but here, the emphasis is already rendered so
the previous HTML tag is rewinded as well and is not correctly closed.
  • Loading branch information...
danlec authored and robin850 committed Apr 5, 2015
1 parent 1242ac1 commit a6c759d7e7cbdd8cb8a1876f97a38b1befe221d5
Showing with 22 additions and 2 deletions.
  1. +7 −0 CHANGELOG.md
  2. +3 −2 ext/redcarpet/markdown.c
  3. +12 −0 test/markdown_test.rb
View
@@ -38,6 +38,13 @@
* Non-alphanumeric chars are now stripped out from generated anchors
(along the lines of Active Support's `#parameterize` method).
## Version 3.2.3
* Avoid rewinding content of a previous inline when autolinking is
enabled.
*Daniel LeCheminant*
## Version 3.2.2
* Consider `script` as a block-level element so it doesn't get included
View
@@ -461,7 +461,7 @@ tag_length(uint8_t *data, size_t size, enum mkd_autolink *autolink)
static void
parse_inline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size)
{
size_t i = 0, end = 0;
size_t i = 0, end = 0, consumed = 0;
uint8_t action = 0;
struct buf work = { 0, 0, 0, 0 };
@@ -486,12 +486,13 @@ parse_inline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t siz
if (end >= size) break;
i = end;
end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i, size - i);
end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i - consumed, size - i);
if (!end) /* no action from the callback */
end = i + 1;
else {
i += end;
end = i;
consumed = i;
}
}
}
View
@@ -344,4 +344,16 @@ def test_superscript_enclosed_in_parenthesis
markdown = render_with({:superscript => true}, "this is the 2^(nd) time")
assert_equal "<p>this is the 2<sup>nd</sup> time</p>\n", markdown
end
def test_no_rewind_into_previous_inline
result = "<p><em>!dl</em><a href=\"mailto:1@danlec.com\">1@danlec.com</a></p>\n"
output = render("_!dl_1@danlec.com", with: [:autolink])
assert_equal result, output
result = "<p>abc123<em><a href=\"http://www.foo.com\">www.foo.com</a></em>@foo.com</p>\n"
output = render("abc123_www.foo.com_@foo.com", with: [:autolink])
assert_equal result, output
end
end

0 comments on commit a6c759d

Please sign in to comment.