diff --git a/modules/markup/html.go b/modules/markup/html.go index f83f70f10..d4d1bc5c6 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -114,16 +114,25 @@ func cutoutVerbosePrefix(prefix string) string { // URLJoin joins url components, like path.Join, but preserving contents func URLJoin(base string, elems ...string) string { - u, err := url.Parse(base) + if !strings.HasSuffix(base, "/") { + base += "/" + } + baseURL, 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() + joinedPath := path.Join(elems...) + argURL, err := url.Parse(joinedPath) + if err != nil { + log.Error(4, "URLJoin: Invalid arg %s", joinedPath) + return "" + } + joinedURL := baseURL.ResolveReference(argURL).String() + if !baseURL.IsAbs() { + return joinedURL[1:] // Removing leading '/' + } + return joinedURL } // RenderIssueIndexPatternOptions options for RenderIssueIndexPattern function diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index 5e783c754..e475e575e 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -83,6 +83,8 @@ func TestURLJoin(t *testing.T) { "a", "b/c/"), newTest("a/b/d", "a/", "b/c/", "/../d/"), + newTest("https://try.gitea.io/a/b/c#d", + "https://try.gitea.io", "a/b", "c#d"), } { assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...)) }