diff --git a/pkg/runner/local_runner.go b/pkg/runner/local_runner.go index 71dede8f..a6558900 100644 --- a/pkg/runner/local_runner.go +++ b/pkg/runner/local_runner.go @@ -91,7 +91,7 @@ func (r *localRunner) openLog(logPath string) (filesystem.FileAppender, error) { // exec.Cmd in localRunner.Run(). It may use different strategies for // resolving the paths of argv[0] and the working directory, depending // on whether the action needs to be run in a chroot() or not. -type CommandCreator func(ctx context.Context, arguments []string, inputRootDirectory *path.Builder, workingDirectory, pathVariable string) (*exec.Cmd, error) +type CommandCreator func(ctx context.Context, arguments []string, inputRootDirectory *path.Builder, workingDirectoryParser path.Parser, pathVariable string) (*exec.Cmd, error) // NewLocalRunner returns a Runner capable of running commands on the // local system directly. @@ -118,7 +118,12 @@ func (r *localRunner) Run(ctx context.Context, request *runner.RunRequest) (*run return nil, util.StatusWrap(err, "Failed to resolve input root directory") } - cmd, err := r.commandCreator(ctx, request.Arguments, inputRootDirectory, request.WorkingDirectory, request.EnvironmentVariables["PATH"]) + workingDirectoryParser, err := path.NewUNIXParser(request.WorkingDirectory) + if err != nil { + return nil, util.StatusWrap(err, "Invalid working directory") + } + + cmd, err := r.commandCreator(ctx, request.Arguments, inputRootDirectory, workingDirectoryParser, request.EnvironmentVariables["PATH"]) if err != nil { return nil, err } diff --git a/pkg/runner/local_runner_unix.go b/pkg/runner/local_runner_unix.go index e31d6fc7..a01d3195 100644 --- a/pkg/runner/local_runner_unix.go +++ b/pkg/runner/local_runner_unix.go @@ -90,11 +90,7 @@ func lookupExecutable(workingDirectory *path.Builder, pathVariable, argv0 string // NewPlainCommandCreator returns a CommandCreator for cases where we don't // need to chroot into the input root directory. func NewPlainCommandCreator(sysProcAttr *syscall.SysProcAttr) CommandCreator { - return func(ctx context.Context, arguments []string, inputRootDirectory *path.Builder, workingDirectoryStr, pathVariable string) (*exec.Cmd, error) { - workingDirectoryParser, err := path.NewUNIXParser(workingDirectoryStr) - if err != nil { - return nil, util.StatusWrap(err, "Invalid working directory") - } + return func(ctx context.Context, arguments []string, inputRootDirectory *path.Builder, workingDirectoryParser path.Parser, pathVariable string) (*exec.Cmd, error) { workingDirectory, scopeWalker := inputRootDirectory.Join(path.VoidScopeWalker) if err := path.Resolve(workingDirectoryParser, scopeWalker); err != nil { return nil, util.StatusWrap(err, "Failed to resolve working directory") @@ -121,7 +117,7 @@ func NewPlainCommandCreator(sysProcAttr *syscall.SysProcAttr) CommandCreator { // NewChrootedCommandCreator returns a CommandCreator for cases where we // need to chroot into the input root directory. func NewChrootedCommandCreator(sysProcAttr *syscall.SysProcAttr) (CommandCreator, error) { - return func(ctx context.Context, arguments []string, inputRootDirectory *path.Builder, workingDirectoryStr, pathVariable string) (*exec.Cmd, error) { + return func(ctx context.Context, arguments []string, inputRootDirectory *path.Builder, workingDirectoryParser path.Parser, pathVariable string) (*exec.Cmd, error) { // The addition of /usr/bin/env is necessary as the PATH resolution // will take place prior to the chroot, so the executable may not be // found by exec.LookPath() inside exec.CommandContext() and may @@ -134,10 +130,6 @@ func NewChrootedCommandCreator(sysProcAttr *syscall.SysProcAttr) (CommandCreator // Set the working relative to be relative to the root // directory of the chrooted environment. - workingDirectoryParser, err := path.NewUNIXParser(workingDirectoryStr) - if err != nil { - return nil, util.StatusWrap(err, "Invalid working directory") - } workingDirectory, scopeWalker := path.RootBuilder.Join(path.VoidScopeWalker) if err := path.Resolve(workingDirectoryParser, scopeWalker); err != nil { return nil, util.StatusWrap(err, "Failed to resolve working directory") diff --git a/pkg/runner/local_runner_windows.go b/pkg/runner/local_runner_windows.go index aacc92ef..860836cf 100644 --- a/pkg/runner/local_runner_windows.go +++ b/pkg/runner/local_runner_windows.go @@ -23,7 +23,7 @@ import ( // NewPlainCommandCreator returns a CommandCreator for cases where we don't // need to chroot into the input root directory. func NewPlainCommandCreator(sysProcAttr *syscall.SysProcAttr) CommandCreator { - return func(ctx context.Context, arguments []string, inputRootDirectory *path.Builder, workingDirectoryStr, pathVariable string) (*exec.Cmd, error) { + return func(ctx context.Context, arguments []string, inputRootDirectory *path.Builder, workingDirectoryParser path.Parser, pathVariable string) (*exec.Cmd, error) { // TODO: This may not work correctly if the action sets // the PATH environment variable explicitly. cmd := exec.CommandContext(ctx, arguments[0], arguments[1:]...) @@ -32,7 +32,7 @@ func NewPlainCommandCreator(sysProcAttr *syscall.SysProcAttr) CommandCreator { // Set the working relative to be relative to the input // root directory. workingDirectory, scopeWalker := inputRootDirectory.Join(path.VoidScopeWalker) - if err := path.Resolve(workingDirectoryStr, scopeWalker); err != nil { + if err := path.Resolve(workingDirectoryParser, scopeWalker); err != nil { return nil, util.StatusWrap(err, "Failed to resolve working directory") } cmd.Dir = filepath.FromSlash(workingDirectory.String())