1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-10 04:07:18 +02:00

fix command escaping

This commit is contained in:
Ryooooooga 2021-03-01 23:16:48 +09:00 committed by Jesse Duffield
parent 03b9db5e0a
commit 50e4e9d58d
5 changed files with 47 additions and 32 deletions

View File

@ -3,7 +3,6 @@ package commands
import ( import (
"fmt" "fmt"
"os/exec" "os/exec"
"strconv"
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/commands/models" "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") splitMessage := strings.Split(message, "\n")
lineArgs := "" lineArgs := ""
for _, line := range splitMessage { 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) command := fmt.Sprintf("git commit %s%s", flags, lineArgs)

View File

@ -8,7 +8,6 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv"
"strings" "strings"
"sync" "sync"
@ -24,14 +23,13 @@ import (
// Platform stores the os state // Platform stores the os state
type Platform struct { type Platform struct {
OS string OS string
CatCmd string CatCmd string
Shell string Shell string
ShellArg string ShellArg string
EscapedQuote string EscapedQuote string
OpenCommand string OpenCommand string
OpenLinkCommand string OpenLinkCommand string
FallbackEscapedQuote string
} }
// OSCommand holds all the os commands // OSCommand holds all the os commands
@ -129,7 +127,7 @@ func (c *OSCommand) ShellCommandFromString(commandStr string) *exec.Cmd {
if c.Platform.OS == "windows" { if c.Platform.OS == "windows" {
quotedCommand = commandStr quotedCommand = commandStr
} else { } else {
quotedCommand = strconv.Quote(commandStr) quotedCommand = c.Quote(commandStr)
} }
shellCommand := fmt.Sprintf("%s %s %s", c.Platform.Shell, c.Platform.ShellArg, quotedCommand) 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 // Quote wraps a message in platform-specific quotation marks
func (c *OSCommand) Quote(message string) string { func (c *OSCommand) Quote(message string) string {
message = strings.Replace(message, "`", "\\`", -1) if c.Platform.OS == "windows" {
escapedQuote := c.Platform.EscapedQuote message = strings.Replace(message, `"`, `"'"'"`, -1)
if strings.Contains(message, c.Platform.EscapedQuote) { message = strings.Replace(message, `\"`, `\\"`, -1)
escapedQuote = c.Platform.FallbackEscapedQuote } 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 return escapedQuote + message + escapedQuote
} }

View File

@ -8,13 +8,12 @@ import (
func getPlatform() *Platform { func getPlatform() *Platform {
return &Platform{ return &Platform{
OS: runtime.GOOS, OS: runtime.GOOS,
CatCmd: "cat", CatCmd: "cat",
Shell: "bash", Shell: "bash",
ShellArg: "-c", ShellArg: "-c",
EscapedQuote: "'", EscapedQuote: `"`,
OpenCommand: "open {{filename}}", OpenCommand: "open {{filename}}",
OpenLinkCommand: "open {{link}}", OpenLinkCommand: "open {{link}}",
FallbackEscapedQuote: "\"",
} }
} }

View File

@ -114,6 +114,8 @@ func TestOSCommandOpenFile(t *testing.T) {
func TestOSCommandQuote(t *testing.T) { func TestOSCommandQuote(t *testing.T) {
osCommand := NewDummyOSCommand() osCommand := NewDummyOSCommand()
osCommand.Platform.OS = "linux"
actual := osCommand.Quote("hello `test`") actual := osCommand.Quote("hello `test`")
expected := osCommand.Platform.EscapedQuote + "hello \\`test\\`" + osCommand.Platform.EscapedQuote expected := osCommand.Platform.EscapedQuote + "hello \\`test\\`" + osCommand.Platform.EscapedQuote
@ -129,7 +131,7 @@ func TestOSCommandQuoteSingleQuote(t *testing.T) {
actual := osCommand.Quote("hello 'test'") 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) assert.EqualValues(t, expected, actual)
} }
@ -142,7 +144,20 @@ func TestOSCommandQuoteDoubleQuote(t *testing.T) {
actual := osCommand.Quote(`hello "test"`) 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) assert.EqualValues(t, expected, actual)
} }

View File

@ -2,11 +2,10 @@ package oscommands
func getPlatform() *Platform { func getPlatform() *Platform {
return &Platform{ return &Platform{
OS: "windows", OS: "windows",
CatCmd: "cmd /c type", CatCmd: "cmd /c type",
Shell: "cmd", Shell: "cmd",
ShellArg: "/c", ShellArg: "/c",
EscapedQuote: `\"`, EscapedQuote: `\"`,
FallbackEscapedQuote: "\\'",
} }
} }