Merge pull request #760 from github/config-whitelist

whitelist the valid keys from .gitconfig
This commit is contained in:
risk danger olson 2015-10-21 13:07:23 -06:00
commit 761a35f51a
3 changed files with 145 additions and 51 deletions

@ -301,12 +301,9 @@ func (c *Configuration) loadGitConfig() bool {
return false
}
uniqRemotes := make(map[string]bool)
c.gitConfig = make(map[string]string)
c.extensions = make(map[string]Extension)
var output string
listOutput, err := git.Config.List()
if err != nil {
panic(fmt.Errorf("Error listing git config: %s", err))
@ -315,59 +312,19 @@ func (c *Configuration) loadGitConfig() bool {
configFile := filepath.Join(LocalWorkingDir, ".gitconfig")
fileOutput, err := git.Config.ListFromFile(configFile)
if err != nil {
panic(fmt.Errorf("Error listing git config from file: %s", err))
panic(fmt.Errorf("Error listing git config from %s: %s", configFile, err))
}
localConfig := filepath.Join(LocalGitDir, "config")
localOutput, err := git.Config.ListFromFile(localConfig)
if err != nil {
panic(fmt.Errorf("Error listing git config from file %s", err))
panic(fmt.Errorf("Error listing git config from %s: %s", localConfig, err))
}
output = fileOutput + "\n" + listOutput + "\n" + localOutput
lines := strings.Split(output, "\n")
for _, line := range lines {
pieces := strings.SplitN(line, "=", 2)
if len(pieces) < 2 {
continue
}
key := strings.ToLower(pieces[0])
value := pieces[1]
c.gitConfig[key] = value
keyParts := strings.Split(key, ".")
if len(keyParts) > 1 && keyParts[0] == "remote" {
remote := keyParts[1]
uniqRemotes[remote] = remote == "origin"
} else if len(keyParts) == 4 && keyParts[0] == "lfs" && keyParts[1] == "extension" {
name := keyParts[2]
ext := c.extensions[name]
switch keyParts[3] {
case "clean":
ext.Clean = value
case "smudge":
ext.Smudge = value
case "priority":
p, err := strconv.Atoi(value)
if err == nil && p >= 0 {
ext.Priority = p
}
}
ext.Name = name
c.extensions[name] = ext
} else if len(keyParts) == 2 && keyParts[0] == "lfs" && keyParts[1] == "fetchinclude" {
for _, inc := range strings.Split(value, ",") {
inc = strings.TrimSpace(inc)
c.fetchIncludePaths = append(c.fetchIncludePaths, inc)
}
} else if len(keyParts) == 2 && keyParts[0] == "lfs" && keyParts[1] == "fetchexclude" {
for _, ex := range strings.Split(value, ",") {
ex = strings.TrimSpace(ex)
c.fetchExcludePaths = append(c.fetchExcludePaths, ex)
}
}
}
uniqRemotes := make(map[string]bool)
c.readGitConfig(fileOutput, uniqRemotes, true)
c.readGitConfig(listOutput, uniqRemotes, false)
c.readGitConfig(localOutput, uniqRemotes, false)
c.remotes = make([]string, 0, len(uniqRemotes))
for remote, isOrigin := range uniqRemotes {
@ -379,3 +336,70 @@ func (c *Configuration) loadGitConfig() bool {
return true
}
func (c *Configuration) readGitConfig(output string, uniqRemotes map[string]bool, whitelisted bool) {
lines := strings.Split(output, "\n")
for _, line := range lines {
pieces := strings.SplitN(line, "=", 2)
if len(pieces) < 2 {
continue
}
allowed := !whitelisted
key := strings.ToLower(pieces[0])
value := pieces[1]
keyParts := strings.Split(key, ".")
if len(keyParts) == 4 && keyParts[0] == "lfs" && keyParts[1] == "extension" {
name := keyParts[2]
ext := c.extensions[name]
switch keyParts[3] {
case "clean":
if whitelisted {
continue
}
ext.Clean = value
case "smudge":
if whitelisted {
continue
}
ext.Smudge = value
case "priority":
allowed = true
p, err := strconv.Atoi(value)
if err == nil && p >= 0 {
ext.Priority = p
}
}
ext.Name = name
c.extensions[name] = ext
} else if len(keyParts) > 1 && keyParts[0] == "remote" {
if whitelisted && (len(keyParts) < 3 || keyParts[2] != "lfsurl") {
continue
}
allowed = true
remote := keyParts[1]
uniqRemotes[remote] = remote == "origin"
}
if !allowed && key != "lfs.url" {
continue
}
c.gitConfig[key] = value
if len(keyParts) == 2 && keyParts[0] == "lfs" && keyParts[1] == "fetchinclude" {
for _, inc := range strings.Split(value, ",") {
inc = strings.TrimSpace(inc)
c.fetchIncludePaths = append(c.fetchIncludePaths, inc)
}
} else if len(keyParts) == 2 && keyParts[0] == "lfs" && keyParts[1] == "fetchexclude" {
for _, ex := range strings.Split(value, ",") {
ex = strings.TrimSpace(ex)
c.fetchExcludePaths = append(c.fetchExcludePaths, ex)
}
}
}
}

70
test/test-config.sh Executable file

@ -0,0 +1,70 @@
#!/usr/bin/env bash
. "test/testlib.sh"
begin_test "default config"
(
set -e
reponame="default-config"
mkdir $reponame
cd $reponame
git init
git remote add origin "$GITSERVER/$reponame"
git lfs env | tee env.log
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs (auth=none)" env.log
git config --file=.gitconfig lfs.url http://gitconfig-file
git lfs env | tee env.log
grep "Endpoint=http://gitconfig-file (auth=none)" env.log
git config lfs.url http://local-gitconfig
git lfs env | tee env.log
grep "Endpoint=http://local-gitconfig (auth=none)" env.log
)
end_test
begin_test "extension config"
(
set -e
git config --global lfs.extension.env-test.clean "env-test-clean"
git config --global lfs.extension.env-test.smudge "env-test-smudge"
git config --global lfs.extension.env-test.priority 0
reponame="extension-config"
mkdir $reponame
cd $reponame
git init
expected0="Extension: env-test
clean = env-test-clean
smudge = env-test-smudge
priority = 0"
[ "$expected0" = "$(git lfs ext)" ]
# any git config takes precedence over .gitconfig
git config --global --unset lfs.extension.env-test.priority
git config --file=.gitconfig lfs.extension.env-test.clean "file-env-test-clean"
git config --file=.gitconfig lfs.extension.env-test.smudge "file-env-test-smudge"
git config --file=.gitconfig lfs.extension.env-test.priority 1
cat .gitconfig
expected1="Extension: env-test
clean = env-test-clean
smudge = env-test-smudge
priority = 1"
[ "$expected1" = "$(GIT_TRACE=5 git lfs ext)" ]
git config lfs.extension.env-test.clean "local-env-test-clean"
git config lfs.extension.env-test.smudge "local-env-test-smudge"
git config lfs.extension.env-test.priority 2
expected2="Extension: env-test
clean = local-env-test-clean
smudge = local-env-test-smudge
priority = 2"
[ "$expected2" = "$(git lfs ext)" ]
)
end_test

@ -244,7 +244,7 @@ begin_test "env with .gitconfig"
echo '[remote "origin"]
lfsurl = http://foobar:8080/
[lfs]
batch = true
batch = false
concurrenttransfers = 5
' > .gitconfig
@ -255,7 +255,7 @@ LocalGitDir=$TRASHDIR/$reponame/.git
LocalGitStorageDir=$TRASHDIR/$reponame/.git
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
ConcurrentTransfers=5
ConcurrentTransfers=3
BatchTransfer=true
$(env | grep "^GIT")
%s