aboutsummaryrefslogtreecommitdiff
path: root/lib/os/exec/exec.go
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2021-08-11 13:26:17 +0700
committerShulhan <ms@kilabit.info>2021-08-11 13:26:17 +0700
commit8148fdb18dbcf22a9c9c724fc9b22b8adb5ee7dd (patch)
treea38bcc3e98f7fa70ffc746a472b55c28a0b7529b /lib/os/exec/exec.go
parent3bfc7c7518d59f78b40145c949b57ea90e05d56c (diff)
downloadpakakeh.go-8148fdb18dbcf22a9c9c724fc9b22b8adb5ee7dd.tar.xz
os/exec: check for escaped backslash when ParseCommandArgs
Given the following string "cmd /a\ b" to ParseCommandArgs now it should return "cmd" and ["/a b"] not ["/a\", "b"], because the space after a is escaped using backslash.
Diffstat (limited to 'lib/os/exec/exec.go')
-rw-r--r--lib/os/exec/exec.go29
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/os/exec/exec.go b/lib/os/exec/exec.go
index bc661f3f..0fed245c 100644
--- a/lib/os/exec/exec.go
+++ b/lib/os/exec/exec.go
@@ -17,10 +17,12 @@ import (
//
// ParseCommandArgs parse the input string into command and arguments.
-// This function detect possible single, double, or back quote on arguments.
+// This function detect single, double, or back quote on arguments; and
+// escaped spaces using backslash.
//
func ParseCommandArgs(in string) (cmd string, args []string) {
var (
+ prev rune
quote rune
cmdArgs []string
)
@@ -40,21 +42,38 @@ func ParseCommandArgs(in string) (cmd string, args []string) {
} else {
sb.WriteRune(r)
}
+ prev = r
continue
}
if r == '\'' || r == '"' || r == '`' {
quote = r
+ prev = r
+ continue
+ }
+ if r == '\\' {
+ if prev == '\\' {
+ sb.WriteRune(r)
+ prev = 0
+ } else {
+ prev = r
+ }
continue
}
if r == ' ' || r == '\t' {
- arg := sb.String()
- if len(arg) > 0 {
- cmdArgs = append(cmdArgs, sb.String())
+ if prev == '\\' {
+ sb.WriteRune(r)
+ } else {
+ arg := sb.String()
+ if len(arg) > 0 {
+ cmdArgs = append(cmdArgs, sb.String())
+ }
+ sb.Reset()
}
- sb.Reset()
+ prev = r
continue
}
sb.WriteRune(r)
+ prev = r
}
arg := sb.String()