diff --git a/pkg/commands/commits.go b/pkg/commands/commits.go index 4d14e1832..27005ebec 100644 --- a/pkg/commands/commits.go +++ b/pkg/commands/commits.go @@ -3,7 +3,6 @@ package commands import ( "fmt" "os/exec" - "strconv" "strings" "github.com/jesseduffield/lazygit/pkg/commands/models" @@ -25,7 +24,7 @@ func (c *GitCommand) Commit(message string, flags string) (*exec.Cmd, error) { splitMessage := strings.Split(message, "\n") lineArgs := "" for _, line := range splitMessage { - lineArgs += fmt.Sprintf(" -m %s", strconv.Quote(line)) + lineArgs += fmt.Sprintf(" -m %s", c.OSCommand.Quote(line)) } command := fmt.Sprintf("git commit %s%s", flags, lineArgs) diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index 2638f3c49..cc66f2cab 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -8,7 +8,6 @@ import ( "os/exec" "path/filepath" "regexp" - "strconv" "strings" "sync" @@ -24,14 +23,13 @@ import ( // Platform stores the os state type Platform struct { - OS string - CatCmd string - Shell string - ShellArg string - EscapedQuote string - OpenCommand string - OpenLinkCommand string - FallbackEscapedQuote string + OS string + CatCmd string + Shell string + ShellArg string + EscapedQuote string + OpenCommand string + OpenLinkCommand string } // OSCommand holds all the os commands @@ -129,7 +127,7 @@ func (c *OSCommand) ShellCommandFromString(commandStr string) *exec.Cmd { if c.Platform.OS == "windows" { quotedCommand = commandStr } else { - quotedCommand = strconv.Quote(commandStr) + quotedCommand = c.Quote(commandStr) } shellCommand := fmt.Sprintf("%s %s %s", c.Platform.Shell, c.Platform.ShellArg, quotedCommand) @@ -245,11 +243,16 @@ func (c *OSCommand) PrepareSubProcess(cmdName string, commandArgs ...string) *ex // Quote wraps a message in platform-specific quotation marks func (c *OSCommand) Quote(message string) string { - message = strings.Replace(message, "`", "\\`", -1) - escapedQuote := c.Platform.EscapedQuote - if strings.Contains(message, c.Platform.EscapedQuote) { - escapedQuote = c.Platform.FallbackEscapedQuote + if c.Platform.OS == "windows" { + message = strings.Replace(message, `"`, `"'"'"`, -1) + message = strings.Replace(message, `\"`, `\\"`, -1) + } else { + message = strings.Replace(message, `\`, `\\`, -1) + message = strings.Replace(message, `"`, `\"`, -1) + message = strings.Replace(message, "`", "\\`", -1) + message = strings.Replace(message, "$", "\\$", -1) } + escapedQuote := c.Platform.EscapedQuote return escapedQuote + message + escapedQuote } diff --git a/pkg/commands/oscommands/os_default_platform.go b/pkg/commands/oscommands/os_default_platform.go index 7ba166428..80ef1aebd 100644 --- a/pkg/commands/oscommands/os_default_platform.go +++ b/pkg/commands/oscommands/os_default_platform.go @@ -8,13 +8,12 @@ import ( func getPlatform() *Platform { return &Platform{ - OS: runtime.GOOS, - CatCmd: "cat", - Shell: "bash", - ShellArg: "-c", - EscapedQuote: "'", - OpenCommand: "open {{filename}}", - OpenLinkCommand: "open {{link}}", - FallbackEscapedQuote: "\"", + OS: runtime.GOOS, + CatCmd: "cat", + Shell: "bash", + ShellArg: "-c", + EscapedQuote: `"`, + OpenCommand: "open {{filename}}", + OpenLinkCommand: "open {{link}}", } } diff --git a/pkg/commands/oscommands/os_test.go b/pkg/commands/oscommands/os_test.go index 1504e4322..e6f3bd33d 100644 --- a/pkg/commands/oscommands/os_test.go +++ b/pkg/commands/oscommands/os_test.go @@ -114,6 +114,8 @@ func TestOSCommandOpenFile(t *testing.T) { func TestOSCommandQuote(t *testing.T) { osCommand := NewDummyOSCommand() + osCommand.Platform.OS = "linux" + actual := osCommand.Quote("hello `test`") expected := osCommand.Platform.EscapedQuote + "hello \\`test\\`" + osCommand.Platform.EscapedQuote @@ -129,7 +131,7 @@ func TestOSCommandQuoteSingleQuote(t *testing.T) { actual := osCommand.Quote("hello 'test'") - expected := osCommand.Platform.FallbackEscapedQuote + "hello 'test'" + osCommand.Platform.FallbackEscapedQuote + expected := osCommand.Platform.EscapedQuote + "hello 'test'" + osCommand.Platform.EscapedQuote assert.EqualValues(t, expected, actual) } @@ -142,7 +144,20 @@ func TestOSCommandQuoteDoubleQuote(t *testing.T) { actual := osCommand.Quote(`hello "test"`) - expected := osCommand.Platform.EscapedQuote + "hello \"test\"" + osCommand.Platform.EscapedQuote + expected := osCommand.Platform.EscapedQuote + `hello \"test\"` + osCommand.Platform.EscapedQuote + + assert.EqualValues(t, expected, actual) +} + +// TestOSCommandQuoteWindows tests the quote function for Windows +func TestOSCommandQuoteWindows(t *testing.T) { + osCommand := NewDummyOSCommand() + + osCommand.Platform.OS = "windows" + + actual := osCommand.Quote(`hello "test"`) + + expected := osCommand.Platform.EscapedQuote + `hello "'"'"test"'"'"` + osCommand.Platform.EscapedQuote assert.EqualValues(t, expected, actual) } diff --git a/pkg/commands/oscommands/os_windows.go b/pkg/commands/oscommands/os_windows.go index 3f4f7e5a1..3e86c803f 100644 --- a/pkg/commands/oscommands/os_windows.go +++ b/pkg/commands/oscommands/os_windows.go @@ -2,11 +2,10 @@ package oscommands func getPlatform() *Platform { return &Platform{ - OS: "windows", - CatCmd: "cmd /c type", - Shell: "cmd", - ShellArg: "/c", - EscapedQuote: `\"`, - FallbackEscapedQuote: "\\'", + OS: "windows", + CatCmd: "cmd /c type", + Shell: "cmd", + ShellArg: "/c", + EscapedQuote: `\"`, } }