Skip to content

Commit a6c759d

Browse files
danlecrobin850
authored andcommitted
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.
1 parent 1242ac1 commit a6c759d

3 files changed

Lines changed: 22 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
* Non-alphanumeric chars are now stripped out from generated anchors
3939
(along the lines of Active Support's `#parameterize` method).
4040

41+
## Version 3.2.3
42+
43+
* Avoid rewinding content of a previous inline when autolinking is
44+
enabled.
45+
46+
*Daniel LeCheminant*
47+
4148
## Version 3.2.2
4249

4350
* Consider `script` as a block-level element so it doesn't get included

ext/redcarpet/markdown.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ tag_length(uint8_t *data, size_t size, enum mkd_autolink *autolink)
461461
static void
462462
parse_inline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size)
463463
{
464-
size_t i = 0, end = 0;
464+
size_t i = 0, end = 0, consumed = 0;
465465
uint8_t action = 0;
466466
struct buf work = { 0, 0, 0, 0 };
467467

@@ -486,12 +486,13 @@ parse_inline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t siz
486486
if (end >= size) break;
487487
i = end;
488488

489-
end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i, size - i);
489+
end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i - consumed, size - i);
490490
if (!end) /* no action from the callback */
491491
end = i + 1;
492492
else {
493493
i += end;
494494
end = i;
495+
consumed = i;
495496
}
496497
}
497498
}

test/markdown_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,4 +344,16 @@ def test_superscript_enclosed_in_parenthesis
344344
markdown = render_with({:superscript => true}, "this is the 2^(nd) time")
345345
assert_equal "<p>this is the 2<sup>nd</sup> time</p>\n", markdown
346346
end
347+
348+
def test_no_rewind_into_previous_inline
349+
result = "<p><em>!dl</em><a href=\"mailto:1@danlec.com\">1@danlec.com</a></p>\n"
350+
output = render("_!dl_1@danlec.com", with: [:autolink])
351+
352+
assert_equal result, output
353+
354+
result = "<p>abc123<em><a href=\"http://www.foo.com\">www.foo.com</a></em>@foo.com</p>\n"
355+
output = render("abc123_www.foo.com_@foo.com", with: [:autolink])
356+
357+
assert_equal result, output
358+
end
347359
end

0 commit comments

Comments
 (0)