From 3a819525d7811dcfb01d928af0e243de4388c456 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 7 Mar 2021 21:44:48 +0100 Subject: commands: minor fixes for the webui open with query - go fmt - add a shorthand - fix displayed webUI URL in the terminal --- repository/repo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'repository') diff --git a/repository/repo.go b/repository/repo.go index eb9296d4..a1dc129e 100644 --- a/repository/repo.go +++ b/repository/repo.go @@ -11,7 +11,7 @@ import ( ) var ( - // ErrNotARepo is the error returned when the git repo root wan't be found + // ErrNotARepo is the error returned when the git repo root can't be found ErrNotARepo = errors.New("not a git repository") // ErrClockNotExist is the error returned when a clock can't be found ErrClockNotExist = errors.New("clock doesn't exist") -- cgit From 9434d2ea5c6da5e856d0bbb02046a5886dfaa600 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 21 Mar 2021 22:37:19 +0100 Subject: repo: fix security issue that could lead to arbitrary code execution see https://blog.golang.org/path-security for details --- repository/git_cli.go | 5 +++-- repository/gogit.go | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'repository') diff --git a/repository/git_cli.go b/repository/git_cli.go index 085b1cda..21cc40e2 100644 --- a/repository/git_cli.go +++ b/repository/git_cli.go @@ -4,8 +4,9 @@ import ( "bytes" "fmt" "io" - "os/exec" "strings" + + "golang.org/x/sys/execabs" ) // gitCli is a helper to launch CLI git commands @@ -21,7 +22,7 @@ func (cli gitCli) runGitCommandWithIO(stdin io.Reader, stdout, stderr io.Writer, // fmt.Printf("[%s] Running git %s\n", path, strings.Join(args, " ")) - cmd := exec.Command("git", args...) + cmd := execabs.Command("git", args...) cmd.Dir = path cmd.Stdin = stdin cmd.Stdout = stdout diff --git a/repository/gogit.go b/repository/gogit.go index bdac259d..f2d2b57e 100644 --- a/repository/gogit.go +++ b/repository/gogit.go @@ -5,7 +5,6 @@ import ( "fmt" "io/ioutil" "os" - "os/exec" "path/filepath" "sort" "strings" @@ -20,6 +19,7 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/filemode" "github.com/go-git/go-git/v5/plumbing/object" + "golang.org/x/sys/execabs" "github.com/MichaelMure/git-bug/util/lamport" ) @@ -261,7 +261,7 @@ func (repo *GoGitRepo) GetCoreEditor() (string, error) { } for _, cmd := range priorities { - if _, err = exec.LookPath(cmd); err == nil { + if _, err = execabs.LookPath(cmd); err == nil { return cmd, nil } -- cgit From 890c014d919f705eac624547031c79205a71321b Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 28 Mar 2021 22:18:01 +0200 Subject: repo: fix various config issues around case insentivity --- repository/config_mem.go | 19 ++++++++++++++++--- repository/config_testing.go | 39 +++++++++++++++++++++++++++++++++++++++ repository/gogit_config.go | 2 +- 3 files changed, 56 insertions(+), 4 deletions(-) (limited to 'repository') diff --git a/repository/config_mem.go b/repository/config_mem.go index 9725e8d5..019bc111 100644 --- a/repository/config_mem.go +++ b/repository/config_mem.go @@ -20,6 +20,7 @@ func NewMemConfig() *MemConfig { } func (mc *MemConfig) StoreString(key, value string) error { + key = normalizeKey(key) mc.config[key] = value return nil } @@ -33,6 +34,7 @@ func (mc *MemConfig) StoreTimestamp(key string, value time.Time) error { } func (mc *MemConfig) ReadAll(keyPrefix string) (map[string]string, error) { + keyPrefix = normalizeKey(keyPrefix) result := make(map[string]string) for key, val := range mc.config { if strings.HasPrefix(key, keyPrefix) { @@ -44,6 +46,7 @@ func (mc *MemConfig) ReadAll(keyPrefix string) (map[string]string, error) { func (mc *MemConfig) ReadString(key string) (string, error) { // unlike git, the mock can only store one value for the same key + key = normalizeKey(key) val, ok := mc.config[key] if !ok { return "", ErrNoConfigEntry @@ -54,9 +57,9 @@ func (mc *MemConfig) ReadString(key string) (string, error) { func (mc *MemConfig) ReadBool(key string) (bool, error) { // unlike git, the mock can only store one value for the same key - val, ok := mc.config[key] - if !ok { - return false, ErrNoConfigEntry + val, err := mc.ReadString(key) + if err != nil { + return false, err } return strconv.ParseBool(val) @@ -78,6 +81,7 @@ func (mc *MemConfig) ReadTimestamp(key string) (time.Time, error) { // RmConfigs remove all key/value pair matching the key prefix func (mc *MemConfig) RemoveAll(keyPrefix string) error { + keyPrefix = normalizeKey(keyPrefix) found := false for key := range mc.config { if strings.HasPrefix(key, keyPrefix) { @@ -92,3 +96,12 @@ func (mc *MemConfig) RemoveAll(keyPrefix string) error { return nil } + +func normalizeKey(key string) string { + // this feels so wrong, but that's apparently how git behave. + // only section and final segment are case insensitive, subsection in between are not. + s := strings.Split(key, ".") + s[0] = strings.ToLower(s[0]) + s[len(s)-1] = strings.ToLower(s[len(s)-1]) + return strings.Join(s, ".") +} diff --git a/repository/config_testing.go b/repository/config_testing.go index 445f8721..f8a2762b 100644 --- a/repository/config_testing.go +++ b/repository/config_testing.go @@ -113,4 +113,43 @@ func testConfig(t *testing.T, config Config) { "section.subsection.subsection.opt1": "foo5", "section.subsection.subsection.opt2": "foo6", }, all) + + // missing section + case insensitive + val, err = config.ReadString("section2.opt1") + require.Error(t, err) + + val, err = config.ReadString("section.opt1") + require.NoError(t, err) + require.Equal(t, "foo", val) + + val, err = config.ReadString("SECTION.OPT1") + require.NoError(t, err) + require.Equal(t, "foo", val) + + _, err = config.ReadString("SECTION2.OPT3") + require.Error(t, err) + + // missing subsection + case insensitive + val, err = config.ReadString("section.subsection.opt1") + require.NoError(t, err) + require.Equal(t, "foo3", val) + + // for some weird reason, subsection ARE case sensitive + _, err = config.ReadString("SECTION.SUBSECTION.OPT1") + require.Error(t, err) + + _, err = config.ReadString("SECTION.SUBSECTION1.OPT1") + require.Error(t, err) + + // missing sub-subsection + case insensitive + val, err = config.ReadString("section.subsection.subsection.opt1") + require.NoError(t, err) + require.Equal(t, "foo5", val) + + // for some weird reason, subsection ARE case sensitive + _, err = config.ReadString("SECTION.SUBSECTION.SUBSECTION.OPT1") + require.Error(t, err) + + _, err = config.ReadString("SECTION.SUBSECTION.SUBSECTION1.OPT1") + require.Error(t, err) } diff --git a/repository/gogit_config.go b/repository/gogit_config.go index ba61adca..891e3ffb 100644 --- a/repository/gogit_config.go +++ b/repository/gogit_config.go @@ -134,7 +134,7 @@ func (cr *goGitConfigReader) ReadString(key string) (string, error) { } return section.Option(optionName), nil default: - subsectionName := strings.Join(split[1:len(split)-2], ".") + subsectionName := strings.Join(split[1:len(split)-1], ".") optionName := split[len(split)-1] if !section.HasSubsection(subsectionName) { return "", ErrNoConfigEntry -- cgit