From 4597d7a73e969ae02a1646c77dc24d23553a0778 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Sun, 13 Oct 2019 19:25:26 -0300 Subject: [PATCH 1/4] Support inline rendering of CUSTOM_URL_SCHEMES --- modules/markup/html.go | 26 ++++++++++++++++++++++++++ modules/markup/markup.go | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/modules/markup/html.go b/modules/markup/html.go index f07993bc4cc8f..1f5c5abe8a13c 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -110,6 +110,32 @@ func FindAllMentions(content string) []string { return ret } +// CustomLinkURLSchemes allows for additional schemes to be detected when parsing links within text +func CustomLinkURLSchemes(schemes []string) { + schemes = append(schemes, "http", "https") + withAuth := make([]string, 0, len(schemes)) + validScheme := regexp.MustCompile(`^[a-z]+$`) + for _, s := range schemes { + if !validScheme.MatchString(s) { + continue + } + without := false + for _, sna := range xurls.SchemesNoAuthority { + if s == sna { + without = true + break + } + } + if without { + s = s + ":" + } else { + s = s + "://" + } + withAuth = append(withAuth, s) + } + linkRegex, _ = xurls.StrictMatchingScheme(strings.Join(withAuth, "|")) +} + // IsSameDomain checks if given url string has the same hostname as current Gitea instance func IsSameDomain(s string) bool { if strings.HasPrefix(s, "/") { diff --git a/modules/markup/markup.go b/modules/markup/markup.go index dc43b533c022a..008b21ab977a3 100644 --- a/modules/markup/markup.go +++ b/modules/markup/markup.go @@ -9,12 +9,16 @@ import ( "strings" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" ) // Init initialize regexps for markdown parsing func Init() { getIssueFullPattern() NewSanitizer() + if len(setting.Markdown.CustomURLSchemes) > 0 { + CustomLinkURLSchemes(setting.Markdown.CustomURLSchemes) + } // since setting maybe changed extensions, this will reload all parser extensions mapping extParsers = make(map[string]Parser) From 64cf7b9c1512b39eea7225c11ac46a5578029e04 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Sun, 13 Oct 2019 19:48:20 -0300 Subject: [PATCH 2/4] Fix lint --- modules/markup/html.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 9ecdd1b0b04ec..1ff7a41cbb0dd 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -109,9 +109,9 @@ func CustomLinkURLSchemes(schemes []string) { } } if without { - s = s + ":" + s += ":" } else { - s = s + "://" + s += "://" } withAuth = append(withAuth, s) } From bb5badd7b11605508bd193dab1a6064609ba9e9a Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Sun, 13 Oct 2019 21:00:00 -0300 Subject: [PATCH 3/4] Add tests --- modules/markup/html_test.go | 19 +++++++++++++++++++ modules/markup/sanitizer.go | 27 ++++++++++++++++----------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index 66e56f71a74d3..91ef320b40927 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -89,6 +89,11 @@ func TestRender_links(t *testing.T) { } // Text that should be turned into URL + defaultCustom := setting.Markdown.CustomURLSchemes + setting.Markdown.CustomURLSchemes = []string{"ftp", "magnet"} + ReplaceSanitizer() + CustomLinkURLSchemes(setting.Markdown.CustomURLSchemes) + test( "https://www.example.com", `

https://www.example.com

`) @@ -131,6 +136,12 @@ func TestRender_links(t *testing.T) { test( "https://username:password@gitea.com", `

https://username:password@gitea.com

`) + test( + "ftp://gitea.com/file.txt", + `

ftp://gitea.com/file.txt

`) + test( + "magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download", + `

magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download

`) // Test that should *not* be turned into URL test( @@ -154,6 +165,14 @@ func TestRender_links(t *testing.T) { test( "www", `

www

`) + test( + "ftps://gitea.com", + `

ftps://gitea.com

`) + + // Restore previous settings + setting.Markdown.CustomURLSchemes = defaultCustom + ReplaceSanitizer() + CustomLinkURLSchemes(setting.Markdown.CustomURLSchemes) } func TestRender_email(t *testing.T) { diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go index fd6f90b2ab1bf..4846d68cd8cb9 100644 --- a/modules/markup/sanitizer.go +++ b/modules/markup/sanitizer.go @@ -28,20 +28,25 @@ var sanitizer = &Sanitizer{} // entire application lifecycle. func NewSanitizer() { sanitizer.init.Do(func() { - sanitizer.policy = bluemonday.UGCPolicy() - // We only want to allow HighlightJS specific classes for code blocks - sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^language-\w+$`)).OnElements("code") + ReplaceSanitizer() + }) +} - // Checkboxes - sanitizer.policy.AllowAttrs("type").Matching(regexp.MustCompile(`^checkbox$`)).OnElements("input") - sanitizer.policy.AllowAttrs("checked", "disabled").OnElements("input") +func ReplaceSanitizer() { + sanitizer = &Sanitizer{} + sanitizer.policy = bluemonday.UGCPolicy() + // We only want to allow HighlightJS specific classes for code blocks + sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^language-\w+$`)).OnElements("code") - // Custom URL-Schemes - sanitizer.policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...) + // Checkboxes + sanitizer.policy.AllowAttrs("type").Matching(regexp.MustCompile(`^checkbox$`)).OnElements("input") + sanitizer.policy.AllowAttrs("checked", "disabled").OnElements("input") - // Allow keyword markup - sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^` + keywordClass + `$`)).OnElements("span") - }) + // Custom URL-Schemes + sanitizer.policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...) + + // Allow keyword markup + sanitizer.policy.AllowAttrs("class").Matching(regexp.MustCompile(`^` + keywordClass + `$`)).OnElements("span") } // Sanitize takes a string that contains a HTML fragment or document and applies policy whitelist. From 8eedcd7d229fc8d2999060a91f5116104e43295b Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Sun, 13 Oct 2019 21:04:30 -0300 Subject: [PATCH 4/4] Fix lint --- modules/markup/sanitizer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go index 4846d68cd8cb9..f873e8105e659 100644 --- a/modules/markup/sanitizer.go +++ b/modules/markup/sanitizer.go @@ -32,6 +32,7 @@ func NewSanitizer() { }) } +// ReplaceSanitizer replaces the current sanitizer to account for changes in settings func ReplaceSanitizer() { sanitizer = &Sanitizer{} sanitizer.policy = bluemonday.UGCPolicy()