diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:36:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:36:04 +0000 |
commit | b09c6d56832eb1718c07d74abf3bc6ae3fe4e030 (patch) | |
tree | d2caec2610d4ea887803ec9e9c3cd77136c448ba /dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs | |
parent | Initial commit. (diff) | |
download | icingadb-b09c6d56832eb1718c07d74abf3bc6ae3fe4e030.tar.xz icingadb-b09c6d56832eb1718c07d74abf3bc6ae3fe4e030.zip |
Adding upstream version 1.1.0.upstream/1.1.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs')
4 files changed, 261 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs.go b/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs.go new file mode 100644 index 0000000..b981cfb --- /dev/null +++ b/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs.go @@ -0,0 +1,102 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package execabs is a drop-in replacement for os/exec +// that requires PATH lookups to find absolute paths. +// That is, execabs.Command("cmd") runs the same PATH lookup +// as exec.Command("cmd"), but if the result is a path +// which is relative, the Run and Start methods will report +// an error instead of running the executable. +// +// See https://blog.golang.org/path-security for more information +// about when it may be necessary or appropriate to use this package. +package execabs + +import ( + "context" + "fmt" + "os/exec" + "path/filepath" + "reflect" + "unsafe" +) + +// ErrNotFound is the error resulting if a path search failed to find an executable file. +// It is an alias for exec.ErrNotFound. +var ErrNotFound = exec.ErrNotFound + +// Cmd represents an external command being prepared or run. +// It is an alias for exec.Cmd. +type Cmd = exec.Cmd + +// Error is returned by LookPath when it fails to classify a file as an executable. +// It is an alias for exec.Error. +type Error = exec.Error + +// An ExitError reports an unsuccessful exit by a command. +// It is an alias for exec.ExitError. +type ExitError = exec.ExitError + +func relError(file, path string) error { + return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path) +} + +// LookPath searches for an executable named file in the directories +// named by the PATH environment variable. If file contains a slash, +// it is tried directly and the PATH is not consulted. The result will be +// an absolute path. +// +// LookPath differs from exec.LookPath in its handling of PATH lookups, +// which are used for file names without slashes. If exec.LookPath's +// PATH lookup would have returned an executable from the current directory, +// LookPath instead returns an error. +func LookPath(file string) (string, error) { + path, err := exec.LookPath(file) + if err != nil && !isGo119ErrDot(err) { + return "", err + } + if filepath.Base(file) == file && !filepath.IsAbs(path) { + return "", relError(file, path) + } + return path, nil +} + +func fixCmd(name string, cmd *exec.Cmd) { + if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) { + // exec.Command was called with a bare binary name and + // exec.LookPath returned a path which is not absolute. + // Set cmd.lookPathErr and clear cmd.Path so that it + // cannot be run. + lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer())) + if *lookPathErr == nil { + *lookPathErr = relError(name, cmd.Path) + } + cmd.Path = "" + } +} + +// CommandContext is like Command but includes a context. +// +// The provided context is used to kill the process (by calling os.Process.Kill) +// if the context becomes done before the command completes on its own. +func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd { + cmd := exec.CommandContext(ctx, name, arg...) + fixCmd(name, cmd) + return cmd + +} + +// Command returns the Cmd struct to execute the named program with the given arguments. +// See exec.Command for most details. +// +// Command differs from exec.Command in its handling of PATH lookups, +// which are used when the program name contains no slashes. +// If exec.Command would have returned an exec.Cmd configured to run an +// executable from the current directory, Command instead +// returns an exec.Cmd that will return an error from Start or Run. +func Command(name string, arg ...string) *exec.Cmd { + cmd := exec.Command(name, arg...) + fixCmd(name, cmd) + return cmd +} diff --git a/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_go118.go b/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_go118.go new file mode 100644 index 0000000..6ab5f50 --- /dev/null +++ b/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_go118.go @@ -0,0 +1,12 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.19 +// +build !go1.19 + +package execabs + +func isGo119ErrDot(err error) bool { + return false +} diff --git a/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_go119.go b/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_go119.go new file mode 100644 index 0000000..1e7a9ad --- /dev/null +++ b/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_go119.go @@ -0,0 +1,15 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.19 +// +build go1.19 + +package execabs + +import "strings" + +func isGo119ErrDot(err error) bool { + // TODO: return errors.Is(err, exec.ErrDot) + return strings.Contains(err.Error(), "current directory") +} diff --git a/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_test.go b/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_test.go new file mode 100644 index 0000000..1e8cf78 --- /dev/null +++ b/dependencies/pkg/mod/golang.org/x/sys@v0.1.0/execabs/execabs_test.go @@ -0,0 +1,132 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package execabs + +import ( + "context" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "runtime" + "testing" +) + +// hasExec reports whether the current system can start new processes +// using os.StartProcess or (more commonly) exec.Command. +// Copied from internal/testenv.HasExec +func hasExec() bool { + switch runtime.GOOS { + case "js", "ios": + return false + } + return true +} + +// mustHaveExec checks that the current system can start new processes +// using os.StartProcess or (more commonly) exec.Command. +// If not, mustHaveExec calls t.Skip with an explanation. +// Copied from internal/testenv.MustHaveExec +func mustHaveExec(t testing.TB) { + if !hasExec() { + t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH) + } +} + +func TestFixCmd(t *testing.T) { + cmd := &exec.Cmd{Path: "hello"} + fixCmd("hello", cmd) + if cmd.Path != "" { + t.Errorf("fixCmd didn't clear cmd.Path") + } + expectedErr := fmt.Sprintf("hello resolves to executable in current directory (.%chello)", filepath.Separator) + if err := cmd.Run(); err == nil { + t.Fatal("Command.Run didn't fail") + } else if err.Error() != expectedErr { + t.Fatalf("Command.Run returned unexpected error: want %q, got %q", expectedErr, err.Error()) + } +} + +func TestCommand(t *testing.T) { + mustHaveExec(t) + + for _, cmd := range []func(string) *Cmd{ + func(s string) *Cmd { return Command(s) }, + func(s string) *Cmd { return CommandContext(context.Background(), s) }, + } { + tmpDir, err := ioutil.TempDir("", "execabs-test") + if err != nil { + t.Fatalf("ioutil.TempDir failed: %s", err) + } + defer os.RemoveAll(tmpDir) + executable := "execabs-test" + if runtime.GOOS == "windows" { + executable += ".exe" + } + if err = ioutil.WriteFile(filepath.Join(tmpDir, executable), []byte{1, 2, 3}, 0111); err != nil { + t.Fatalf("ioutil.WriteFile failed: %s", err) + } + cwd, err := os.Getwd() + if err != nil { + t.Fatalf("os.Getwd failed: %s", err) + } + defer os.Chdir(cwd) + if err = os.Chdir(tmpDir); err != nil { + t.Fatalf("os.Chdir failed: %s", err) + } + if runtime.GOOS != "windows" { + // add "." to PATH so that exec.LookPath looks in the current directory on + // non-windows platforms as well + origPath := os.Getenv("PATH") + defer os.Setenv("PATH", origPath) + os.Setenv("PATH", fmt.Sprintf(".:%s", origPath)) + } + expectedErr := fmt.Sprintf("execabs-test resolves to executable in current directory (.%c%s)", filepath.Separator, executable) + if err = cmd("execabs-test").Run(); err == nil { + t.Fatalf("Command.Run didn't fail when exec.LookPath returned a relative path") + } else if err.Error() != expectedErr { + t.Errorf("Command.Run returned unexpected error: want %q, got %q", expectedErr, err.Error()) + } + } +} + +func TestLookPath(t *testing.T) { + mustHaveExec(t) + + tmpDir, err := ioutil.TempDir("", "execabs-test") + if err != nil { + t.Fatalf("ioutil.TempDir failed: %s", err) + } + defer os.RemoveAll(tmpDir) + executable := "execabs-test" + if runtime.GOOS == "windows" { + executable += ".exe" + } + if err = ioutil.WriteFile(filepath.Join(tmpDir, executable), []byte{1, 2, 3}, 0111); err != nil { + t.Fatalf("ioutil.WriteFile failed: %s", err) + } + cwd, err := os.Getwd() + if err != nil { + t.Fatalf("os.Getwd failed: %s", err) + } + defer os.Chdir(cwd) + if err = os.Chdir(tmpDir); err != nil { + t.Fatalf("os.Chdir failed: %s", err) + } + if runtime.GOOS != "windows" { + // add "." to PATH so that exec.LookPath looks in the current directory on + // non-windows platforms as well + origPath := os.Getenv("PATH") + defer os.Setenv("PATH", origPath) + os.Setenv("PATH", fmt.Sprintf(".:%s", origPath)) + } + expectedErr := fmt.Sprintf("execabs-test resolves to executable in current directory (.%c%s)", filepath.Separator, executable) + if _, err := LookPath("execabs-test"); err == nil { + t.Fatalf("LookPath didn't fail when finding a non-relative path") + } else if err.Error() != expectedErr { + t.Errorf("LookPath returned unexpected error: want %q, got %q", expectedErr, err.Error()) + } +} |