Skip to content

Commit

Permalink
Quote state exec arguments on Windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchell-as committed Mar 22, 2024
1 parent d47d8ff commit 6c1db9c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
9 changes: 8 additions & 1 deletion internal/runners/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,15 @@ func (s *Exec) Run(params *Params, args ...string) (rerr error) {
lang := language.Bash
scriptArgs := fmt.Sprintf(`%q "$@"`, exeTarget)
if strings.Contains(s.subshell.Binary(), "cmd") {
// Note: we cannot simply use the %* variable, because its expansion does not quote individual
// arguments. We need to manually quote and pass "%1" "%2" [...] "%255"
// See https://ss64.com/nt/syntax-args.html
lang = language.Batch
scriptArgs = fmt.Sprintf("@ECHO OFF\n%q %%*", exeTarget)
params := make([]string, 256)
for i := 1; i <= 255; i++ {
params[i] = fmt.Sprintf(`"%%%d"`, i)
}
scriptArgs = fmt.Sprintf(`@ECHO OFF\n%q %s`, exeTarget, strings.Join(params, " "))
}

sf, err := scriptfile.New(lang, "state-exec", scriptArgs)
Expand Down
20 changes: 20 additions & 0 deletions test/integration/exec_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,26 @@ func (suite *ExecIntegrationTestSuite) TestExecWithPath() {

}

func (suite *ExecIntegrationTestSuite) TestExecQuotedArgs() {
suite.OnlyRunForTags(tagsuite.Exec)
ts := e2e.New(suite.T(), false)
defer ts.Close()

cp := ts.Spawn("checkout", "ActiveState-CLI/Perl-5.32", ".")
cp.Expect("Skipping runtime setup")
cp.Expect("Checked out project")
cp.ExpectExitCode(0)

fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "testargs.txt"), []byte(`printf "Argument: '%s'.\n", $ARGV[0];`))

cp = ts.SpawnWithOpts(
e2e.OptArgs("exec", "perl", "testargs.txt", "a<b"),
e2e.OptAppendEnv(constants.DisableRuntime+"=false"),
)
cp.Expect("Argument: 'a<b'.", e2e.RuntimeSourcingTimeoutOpt)
cp.ExpectExitCode(0)
}

func TestExecIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(ExecIntegrationTestSuite))
}

0 comments on commit 6c1db9c

Please sign in to comment.