aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2019-03-12 02:23:34 +0000
committertechknowlogick <matti@mdranta.net>2019-03-11 22:23:34 -0400
commitb2e9894988a8cb486f8838f4bf532401124802c4 (patch)
tree7fc62cb89d394f0edb026726c9a732b35ab47f19
parent663874e8bee253dcaa95b03adb519c5685774351 (diff)
downloadgitea-b2e9894988a8cb486f8838f4bf532401124802c4.tar.gz
gitea-b2e9894988a8cb486f8838f4bf532401124802c4.zip
Fix reported issue in repo description (#6306)
-rw-r--r--models/repo.go8
-rw-r--r--modules/markup/html.go48
2 files changed, 53 insertions, 3 deletions
diff --git a/models/repo.go b/models/repo.go
index 4d7320a789..2822f7d718 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(`<a href="%[1]s" target="_blank" rel="noopener noreferrer">%[1]s</a>`, 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 036b664b00..20a158b1c5 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("<body>")
var byteBodyTagClosing = []byte("</body>")
@@ -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
+}