Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Aug 30, 2024. It is now read-only.
/coder-v1-cliPublic archive

Commit259876f

Browse files
committed
fix: Escape shell arguments
The commands passed to "coder sh" are passed as a single argumentto "sh -c", so we need to shell-escape the command we pass.This change escapes spaces, backslash, and quotes.
1 parentb8067c0 commit259876f

File tree

2 files changed

+83
-5
lines changed

2 files changed

+83
-5
lines changed

‎internal/cmd/shell.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,54 @@ coder sh front-end-dev cat ~/config.json`,
8080
}
8181
}
8282

83+
// shellEscape escapes an argument so that we can pass it 'sh -c'
84+
// and have it do the right thing.
85+
//
86+
// Use this to ensure that the result of a command running in
87+
// the development environment behaves the same as the command
88+
// running via "coder sh".
89+
//
90+
// For example:
91+
//
92+
// $ coder sh env
93+
// $ go run ~/test.go 1 2 "3 4" '"abc def" \\abc' 5 6 "7 8 9"
94+
//
95+
// should produce the same output as:
96+
//
97+
// $ coder sh go run ~/test.go 1 2 "3 4" '"abc def" \\abc' 5 6 "7 8 9"
98+
funcshellEscape(argstring)string {
99+
r:=strings.NewReplacer(`\`,`\\`,`"`,`\"`,`'`,`\'`,` `,`\ `)
100+
returnr.Replace(arg)
101+
}
102+
83103
funcshell(cmd*cobra.Command,cmdArgs []string)error {
84104
ctx:=cmd.Context()
85-
command:="sh"
86-
args:= []string{"-c"}
105+
106+
varcommandstring
107+
varargs []string
87108
iflen(cmdArgs)>1 {
88-
args=append(args,strings.Join(cmdArgs[1:]," "))
109+
varescapedArgs strings.Builder
110+
111+
fori,arg:=rangecmdArgs[1:] {
112+
escapedArgs.WriteString(shellEscape(arg))
113+
114+
// Add spaces between arguments, except the last argument
115+
ifi<len(cmdArgs)-2 {
116+
escapedArgs.WriteByte(' ')
117+
}
118+
}
119+
120+
command="/bin/sh"
121+
args= []string{"-c"}
122+
args=append(args,escapedArgs.String())
89123
}else {
90124
// Bring user into shell if no command is specified.
91125
shell:="$(getent passwd $(id -u) | cut -d: -f 7)"
92-
name:="-$(basename "+shell+")"
93-
args=append(args,fmt.Sprintf("exec -a %q %q",name,shell))
126+
127+
// force bash for the '-l' flag to the exec built-in
128+
command="/bin/bash"
129+
args= []string{"-c"}
130+
args=append(args,fmt.Sprintf("exec -l %q",shell))
94131
}
95132

96133
envName:=cmdArgs[0]

‎internal/cmd/shell_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package cmd
2+
3+
import"testing"
4+
5+
funcTestShellEscape(t*testing.T) {
6+
t.Parallel()
7+
8+
tests:= []struct {
9+
Namestring
10+
Inputstring
11+
Escapedstring
12+
}{
13+
{
14+
Name:"single space",
15+
Input:"hello world",
16+
Escaped:`hello\ world`,
17+
},
18+
{
19+
Name:"multiple spaces",
20+
Input:"test message hello world",
21+
Escaped:`test\ message\ hello\ \ world`,
22+
},
23+
{
24+
Name:"mixed quotes",
25+
Input:`"''"`,
26+
Escaped:`\"\'\'\"`,
27+
},
28+
{
29+
Name:"mixed escaped quotes",
30+
Input:`"'\"\"'"`,
31+
Escaped:`\"\'\\\"\\\"\'\"`,
32+
},
33+
}
34+
35+
for_,test:=rangetests {
36+
ife,a:=test.Escaped,shellEscape(test.Input);e!=a {
37+
t.Fatalf("test %q failed; expected: %q, got %q (input: %q)",
38+
test.Name,test.Escaped,a,test.Input)
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp