From 9fc8c9d8660c52c8390ba80e50556577e179b984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vytautas=20=C5=A0altenis?= Date: Sat, 25 Jan 2014 21:42:34 +0200 Subject: [PATCH] Fix bug with overzealous autolink processing When the source Markdown contains an anchor tag with URL as link text (i.e. http://foo.bar), autolink converts that link text into another anchor tag, which is nonsense. Detect this situation with regexp and early exit autolink processing. --- inline.go | 19 +++++++++++++++++++ inline_test.go | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/inline.go b/inline.go index 0348dbf..d83404e 100644 --- a/inline.go +++ b/inline.go @@ -15,9 +15,14 @@ package blackfriday import ( "bytes" + "regexp" "strconv" ) +var ( + anchorRe = regexp.MustCompile(`^(]+")?\s?>` + urlRe + `<\/a>)`) +) + // Functions to parse text within a block // Each function returns the number of chars taken care of // data is the complete block being rendered @@ -618,6 +623,20 @@ func autoLink(p *parser, out *bytes.Buffer, data []byte, offset int) int { return 0 } + // Now a more expensive check to see if we're not inside an anchor element + anchorStart := offset + offsetFromAnchor := 0 + for anchorStart > 0 && data[anchorStart] != '<' { + anchorStart-- + offsetFromAnchor++ + } + + anchorStr := anchorRe.Find(data[anchorStart:]) + if anchorStr != nil { + out.Write(anchorStr[offsetFromAnchor:]) + return len(anchorStr) - offsetFromAnchor + } + // scan backward for a word boundary rewind := 0 for offset-rewind > 0 && rewind <= 7 && isletter(data[offset-rewind-1]) { diff --git a/inline_test.go b/inline_test.go index 57bef81..7cb3cdf 100644 --- a/inline_test.go +++ b/inline_test.go @@ -674,6 +674,21 @@ func TestAutoLink(t *testing.T) { "even a > can be escaped &etc>\n", "

even a > can be escaped " + "http://new.com?q=>&etc

\n", + + "http://fancy.com\n", + "

http://fancy.com

\n", + + "This is a link\n", + "

This is a link

\n", + + "http://www.fancy.com/A_B.pdf\n", + "

http://www.fancy.com/A_B.pdf

\n", + + "(http://www.fancy.com/A_B (\n", + "

(http://www.fancy.com/A_B (

\n", + + "(http://www.fancy.com/A_B (part two: http://www.fancy.com/A_B)).\n", + "

(http://www.fancy.com/A_B (part two: http://www.fancy.com/A_B)).

\n", } doTestsInline(t, tests) }