From b2e9894988a8cb486f8838f4bf532401124802c4 Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 12 Mar 2019 02:23:34 +0000 Subject: [PATCH] Fix reported issue in repo description (#6306) --- models/repo.go | 8 ++++--- modules/markup/html.go | 48 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/models/repo.go b/models/repo.go index 4d7320a78..2822f7d71 100644 --- a/models/repo.go +++ b/models/repo.go @@ -722,10 +722,12 @@ var ( // DescriptionHTML does special handles to description and return HTML string. func (repo *Repository) DescriptionHTML() template.HTML { - sanitize := func(s string) string { - return fmt.Sprintf(`%[1]s`, s) + desc, err := markup.RenderDescriptionHTML([]byte(repo.Description), repo.HTMLURL(), repo.ComposeMetas()) + if err != nil { + log.Error(4, "Failed to render description for %s (ID: %d): %v", repo.Name, repo.ID, err) + return template.HTML(markup.Sanitize(repo.Description)) } - return template.HTML(descPattern.ReplaceAllStringFunc(markup.Sanitize(repo.Description), sanitize)) + return template.HTML(markup.Sanitize(string(desc))) } // LocalCopyPath returns the local repository copy path. diff --git a/modules/markup/html.go b/modules/markup/html.go index 036b664b0..20a158b1c 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -227,6 +227,23 @@ func RenderCommitMessage( return ctx.postProcess(rawHTML) } +// RenderDescriptionHTML will use similar logic as PostProcess, but will +// use a single special linkProcessor. +func RenderDescriptionHTML( + rawHTML []byte, + urlPrefix string, + metas map[string]string, +) ([]byte, error) { + ctx := &postProcessCtx{ + metas: metas, + urlPrefix: urlPrefix, + procs: []processor{ + descriptionLinkProcessor, + }, + } + return ctx.postProcess(rawHTML) +} + var byteBodyTag = []byte("") var byteBodyTagClosing = []byte("") @@ -658,3 +675,34 @@ func genDefaultLinkProcessor(defaultLink string) processor { node.FirstChild, node.LastChild = ch, ch } } + +// descriptionLinkProcessor creates links for DescriptionHTML +func descriptionLinkProcessor(ctx *postProcessCtx, node *html.Node) { + m := linkRegex.FindStringIndex(node.Data) + if m == nil { + return + } + uri := node.Data[m[0]:m[1]] + replaceContent(node, m[0], m[1], createDescriptionLink(uri, uri)) +} + +func createDescriptionLink(href, content string) *html.Node { + textNode := &html.Node{ + Type: html.TextNode, + Data: content, + } + linkNode := &html.Node{ + FirstChild: textNode, + LastChild: textNode, + Type: html.ElementNode, + Data: "a", + DataAtom: atom.A, + Attr: []html.Attribute{ + {Key: "href", Val: href}, + {Key: "target", Val: "_blank"}, + {Key: "rel", Val: "noopener noreferrer"}, + }, + } + textNode.Parent = linkNode + return linkNode +}