aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
authorUnknwon <u@gogs.io>2017-04-04 19:40:46 -0400
committerUnknwon <u@gogs.io>2017-04-04 19:40:46 -0400
commitae1d50d19a4ffe1b527429978ebff6fdd35b71e8 (patch)
tree65a54a5c224ecf125cf827b13039eab0f2a24359 /models
parentfe25effe7c3d3a2b27d450747ae321b9795ebdc6 (diff)
models/mirror: escape credentials before write mirror address (#4014)
Special characters such as '@', ';', '#' and ':' could occur in password portion of credentials, which breaks the interpretation and saves 'config' file in with extra characters that are not recognized by Git (due to INI library).
Diffstat (limited to 'models')
-rw-r--r--models/mirror.go30
-rw-r--r--models/mirror_test.go28
2 files changed, 57 insertions, 1 deletions
diff --git a/models/mirror.go b/models/mirror.go
index 4820520e..46ef7452 100644
--- a/models/mirror.go
+++ b/models/mirror.go
@@ -6,6 +6,7 @@ package models
import (
"fmt"
+ "net/url"
"strings"
"time"
@@ -119,6 +120,33 @@ func (m *Mirror) FullAddress() string {
return m.address
}
+// escapeCredentials returns mirror address with escaped credentials.
+func escapeMirrorCredentials(addr string) string {
+ // Find end of credentials (start of path)
+ end := strings.LastIndex(addr, "@")
+ if end == -1 {
+ return addr
+ }
+
+ // Find delimiter of credentials (end of username)
+ start := strings.Index(addr, "://")
+ if start == -1 {
+ return addr
+ }
+ start += 3
+ delim := strings.Index(addr[:start], ":")
+ if delim == -1 {
+ return addr
+ }
+ delim += 1
+
+ if start+delim > end {
+ return addr // No password portion presented
+ }
+
+ return addr[:start+delim] + url.QueryEscape(addr[start+delim:end]) + addr[end:]
+}
+
// SaveAddress writes new address to Git repository config.
func (m *Mirror) SaveAddress(addr string) error {
configPath := m.Repo.GitConfigPath()
@@ -127,7 +155,7 @@ func (m *Mirror) SaveAddress(addr string) error {
return fmt.Errorf("Load: %v", err)
}
- cfg.Section("remote \"origin\"").Key("url").SetValue(addr)
+ cfg.Section("remote \"origin\"").Key("url").SetValue(escapeMirrorCredentials(addr))
return cfg.SaveToIndent(configPath, "\t")
}
diff --git a/models/mirror_test.go b/models/mirror_test.go
new file mode 100644
index 00000000..6b23df1c
--- /dev/null
+++ b/models/mirror_test.go
@@ -0,0 +1,28 @@
+// Copyright 2017 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package models
+
+import (
+ "testing"
+
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+func Test_escapeMirrorCredentials(t *testing.T) {
+ Convey("Escape credentials in mirror address", t, func() {
+ testCases := []string{
+ "http://localhost:3000/user/repo.git", "http://localhost:3000/user/repo.git",
+ "http://user@localhost:3000/user/repo.git", "http://user@localhost:3000/user/repo.git",
+ "http://user:@localhost:3000/user/repo.git", "http://user:@localhost:3000/user/repo.git",
+ "http://user:password@localhost:3000/user/repo.git", "http://user:password@localhost:3000/user/repo.git",
+ "http://user:my:secure;password@localhost:3000/user/repo.git", "http://user:my%3Asecure%3Bpassword@localhost:3000/user/repo.git",
+ "http://user:my@secure#password@localhost:3000/user/repo.git", "http://user:my%40secure%23password@localhost:3000/user/repo.git",
+ }
+
+ for i := 0; i < len(testCases); i += 2 {
+ So(escapeMirrorCredentials(testCases[i]), ShouldEqual, testCases[i+1])
+ }
+ })
+}