Skip to content

Commit c7bbfd8

Browse files
techknowlogicklunny
authored andcommitted
backport 6306 (#6308)
1 parent 59a64c0 commit c7bbfd8

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

models/repo.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -719,10 +719,12 @@ var (
719719

720720
// DescriptionHTML does special handles to description and return HTML string.
721721
func (repo *Repository) DescriptionHTML() template.HTML {
722-
sanitize := func(s string) string {
723-
return fmt.Sprintf(`<a href="%[1]s" target="_blank" rel="noopener noreferrer">%[1]s</a>`, s)
722+
desc, err := markup.RenderDescriptionHTML([]byte(repo.Description), repo.HTMLURL(), repo.ComposeMetas())
723+
if err != nil {
724+
log.Error(4, "Failed to render description for %s (ID: %d): %v", repo.Name, repo.ID, err)
725+
return template.HTML(markup.Sanitize(repo.Description))
724726
}
725-
return template.HTML(descPattern.ReplaceAllStringFunc(markup.Sanitize(repo.Description), sanitize))
727+
return template.HTML(markup.Sanitize(string(desc)))
726728
}
727729

728730
// LocalCopyPath returns the local repository copy path.

modules/markup/html.go

+48
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,23 @@ func RenderCommitMessage(
234234
return ctx.postProcess(rawHTML)
235235
}
236236

237+
// RenderDescriptionHTML will use similar logic as PostProcess, but will
238+
// use a single special linkProcessor.
239+
func RenderDescriptionHTML(
240+
rawHTML []byte,
241+
urlPrefix string,
242+
metas map[string]string,
243+
) ([]byte, error) {
244+
ctx := &postProcessCtx{
245+
metas: metas,
246+
urlPrefix: urlPrefix,
247+
procs: []processor{
248+
descriptionLinkProcessor,
249+
},
250+
}
251+
return ctx.postProcess(rawHTML)
252+
}
253+
237254
var byteBodyTag = []byte("<body>")
238255
var byteBodyTagClosing = []byte("</body>")
239256

@@ -668,3 +685,34 @@ func genDefaultLinkProcessor(defaultLink string) processor {
668685
node.FirstChild, node.LastChild = ch, ch
669686
}
670687
}
688+
689+
// descriptionLinkProcessor creates links for DescriptionHTML
690+
func descriptionLinkProcessor(ctx *postProcessCtx, node *html.Node) {
691+
m := linkRegex.FindStringIndex(node.Data)
692+
if m == nil {
693+
return
694+
}
695+
uri := node.Data[m[0]:m[1]]
696+
replaceContent(node, m[0], m[1], createDescriptionLink(uri, uri))
697+
}
698+
699+
func createDescriptionLink(href, content string) *html.Node {
700+
textNode := &html.Node{
701+
Type: html.TextNode,
702+
Data: content,
703+
}
704+
linkNode := &html.Node{
705+
FirstChild: textNode,
706+
LastChild: textNode,
707+
Type: html.ElementNode,
708+
Data: "a",
709+
DataAtom: atom.A,
710+
Attr: []html.Attribute{
711+
{Key: "href", Val: href},
712+
{Key: "target", Val: "_blank"},
713+
{Key: "rel", Val: "noopener noreferrer"},
714+
},
715+
}
716+
textNode.Parent = linkNode
717+
return linkNode
718+
}

0 commit comments

Comments
 (0)