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).
master
Unknwon 2017-04-04 19:40:46 -04:00
parent fe25effe7c
commit ae1d50d19a
No known key found for this signature in database
GPG Key ID: 25B575AE3213B2B3
4 changed files with 59 additions and 3 deletions

View File

@ -16,7 +16,7 @@ import (
"github.com/gogits/gogs/pkg/setting"
)
const APP_VER = "0.11.2.0404"
const APP_VER = "0.11.3.0404"
func init() {
setting.AppVer = APP_VER

View File

@ -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")
}

28
models/mirror_test.go Normal file
View File

@ -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])
}
})
}

View File

@ -1 +1 @@
0.11.2.0404
0.11.3.0404