From b0cf75df988a0c7c4d266c1cffcad0d1a25ac547 Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Sun, 27 May 2018 19:57:48 +0200 Subject: [PATCH 1/2] Replace '%28' with '#' Add test case Signed-off-by: Jonas Franz --- modules/util/util.go | 3 ++- modules/util/util_test.go | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/util/util.go b/modules/util/util.go index 3a0411f64b800..b45bd35b0496f 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -7,6 +7,7 @@ package util import ( "net/url" "path" + "strings" "code.gitea.io/gitea/modules/log" ) @@ -65,7 +66,7 @@ func URLJoin(base string, elems ...string) string { joinArgs = append(joinArgs, u.Path) joinArgs = append(joinArgs, elems...) u.Path = path.Join(joinArgs...) - return u.String() + return strings.Replace(u.String(), "%23", "#", 1) } // Min min of two ints diff --git a/modules/util/util_test.go b/modules/util/util_test.go index cc5875263a3f4..67d9efe1d2f86 100644 --- a/modules/util/util_test.go +++ b/modules/util/util_test.go @@ -30,6 +30,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...)) } From fb46c02135c1416e1418a2732682a39557d37f55 Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Mon, 28 May 2018 23:18:59 +0200 Subject: [PATCH 2/2] Use ResolveReference instead of strings.Replace Signed-off-by: Jonas Franz --- modules/util/util.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/modules/util/util.go b/modules/util/util.go index b45bd35b0496f..4bd2b843f73c4 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -57,16 +57,25 @@ func Max(a, b int) int { // 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 strings.Replace(u.String(), "%23", "#", 1) + 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 } // Min min of two ints