diff --git a/modules/markdown/markdown.go b/modules/markdown/markdown.go index 1f890cc8223..d360dfb8419 100644 --- a/modules/markdown/markdown.go +++ b/modules/markdown/markdown.go @@ -19,6 +19,7 @@ import ( "golang.org/x/net/html" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/setting" ) @@ -213,36 +214,17 @@ func cutoutVerbosePrefix(prefix string) string { } // URLJoin joins url components, like path.Join, but preserving contents -func URLJoin(elem ...string) string { - res := "" - last := len(elem) - 1 - for i, item := range elem { - res += item - if i != last && !strings.HasSuffix(res, "/") { - res += "/" - } - } - cwdIndex := strings.Index(res, "/./") - for cwdIndex != -1 { - res = strings.Replace(res, "/./", "/", 1) - cwdIndex = strings.Index(res, "/./") - } - upIndex := strings.Index(res, "/..") - for upIndex != -1 { - res = strings.Replace(res, "/..", "", 1) - prevStart := -1 - for i := upIndex - 1; i >= 0; i-- { - if res[i] == '/' { - prevStart = i - break - } - } - if prevStart != -1 { - res = res[:prevStart] + res[upIndex:] - } - upIndex = strings.Index(res, "/..") - } - return res +func URLJoin(base string, elems ...string) string { + u, err := url.Parse(base) + if err != nil { + log.Error(4, "URLJoin: Invalid base URL %s", base) + return "" + } + joinArgs := make([]string, 0, len(elems)+1) + joinArgs = append(joinArgs, u.Path) + joinArgs = append(joinArgs, elems...) + u.Path = path.Join(joinArgs...) + return u.String() } // RenderIssueIndexPattern renders issue indexes to corresponding links. diff --git a/modules/markdown/markdown_test.go b/modules/markdown/markdown_test.go index e6bc3683c61..9a1dafa7134 100644 --- a/modules/markdown/markdown_test.go +++ b/modules/markdown/markdown_test.go @@ -59,6 +59,27 @@ func testRenderIssueIndexPattern(t *testing.T, input, expected string, metas map string(RenderIssueIndexPattern([]byte(input), AppSubURL, metas))) } +func TestURLJoin(t *testing.T) { + type test struct { + Expected string + Base string + Elements []string + } + newTest := func(expected, base string, elements ...string) test { + return test{Expected: expected, Base: base, Elements: elements} + } + for _, test := range []test{ + newTest("https://try.gitea.io/a/b/c", + "https://try.gitea.io", "a/b", "c"), + newTest("https://try.gitea.io/a/b/c", + "https://try.gitea.io/", "/a/b/", "/c/"), + newTest("https://try.gitea.io/a/c", + "https://try.gitea.io/", "/a/./b/", "../c/"), + } { + assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...)) + } +} + func TestRender_IssueIndexPattern(t *testing.T) { // numeric: render inputs without valid mentions test := func(s string) { @@ -641,8 +662,8 @@ func testAnswers(baseURLContent, baseURLImages string) []string { `
Wiki! Enjoy :)
Ideas and codes
@@ -650,8 +671,8 @@ func testAnswers(baseURLContent, baseURLImages string) []string {- | Installation | ++ | Installation |
---|---|---|---|
- | Usage | ++ | Usage |