diff --git a/html.go b/html.go index 2032b7d..ac62d8b 100644 --- a/html.go +++ b/html.go @@ -74,6 +74,8 @@ var ( tagWhitelist = regexp.MustCompile(`^(<\/?(` + strings.Join(tags, "|") + `)>|<(br|hr)\s?\/?>)$`) anchorClean = regexp.MustCompile(`^(]+")?\s?>|<\/a>)$`) imgClean = regexp.MustCompile(`^(]*")?(\stitle="[^"<>]*")?\s?\/?>)$`) + // TODO: improve this regexp to catch all possible entities: + htmlEntity = regexp.MustCompile(`&[a-z]{2,5};`) ) // Html is a type that implements the Renderer interface for HTML output. @@ -164,6 +166,16 @@ func attrEscape(out *bytes.Buffer, src []byte) { } } +func entityEscapeWithSkip(out *bytes.Buffer, src []byte, skipRanges [][]int) { + end := 0 + for _, rang := range skipRanges { + attrEscape(out, src[end:rang[0]]) + out.Write(src[rang[0]:rang[1]]) + end = rang[1] + } + attrEscape(out, src[end:]) +} + func (options *Html) GetFlags() int { return options.flags } @@ -408,10 +420,11 @@ func (options *Html) Paragraph(out *bytes.Buffer, text func() bool) { } func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) { + skipRanges := htmlEntity.FindAllIndex(link, -1) if options.flags&HTML_SAFELINK != 0 && !isSafeLink(link) && kind != LINK_TYPE_EMAIL { // mark it but don't link it if it is not a safe link: no smartypants out.WriteString("") - attrEscape(out, link) + entityEscapeWithSkip(out, link, skipRanges) out.WriteString("") return } @@ -420,7 +433,7 @@ func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) { if kind == LINK_TYPE_EMAIL { out.WriteString("mailto:") } - attrEscape(out, link) + entityEscapeWithSkip(out, link, skipRanges) out.WriteString("\">") // Pretty print: if we get an email address as @@ -432,7 +445,7 @@ func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) { case bytes.HasPrefix(link, []byte("mailto:")): attrEscape(out, link[len("mailto:"):]) default: - attrEscape(out, link) + entityEscapeWithSkip(out, link, skipRanges) } out.WriteString("") diff --git a/inline_test.go b/inline_test.go index a4be3ba..aea6bf1 100644 --- a/inline_test.go +++ b/inline_test.go @@ -692,6 +692,12 @@ func TestAutoLink(t *testing.T) { "http://www.foo.com
\n", "

http://www.foo.com

\n", + + "http://foo.com/viewtopic.php?f=18&t=297", + "

http://foo.com/viewtopic.php?f=18&t=297

\n", + + "http://foo.com/viewtopic.php?param="18"zz", + "

http://foo.com/viewtopic.php?param="18"zz

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