mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
os/exec: add GODEBUG setting to opt out of ErrDot changes
The changes are likely to break users, and we need to make it easy to unbreak without code changes. For #43724. Fixes #53962. Change-Id: I105c5d6c801d354467e0cefd268189c18846858e Reviewed-on: https://go-review.googlesource.com/c/go/+/419794 Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
462b78fe70
commit
027855e8d8
6 changed files with 68 additions and 37 deletions
|
|
@ -177,7 +177,11 @@ var depsRules = `
|
||||||
|
|
||||||
os/signal, STR
|
os/signal, STR
|
||||||
< path/filepath
|
< path/filepath
|
||||||
< io/ioutil, os/exec;
|
< io/ioutil;
|
||||||
|
|
||||||
|
os < internal/godebug;
|
||||||
|
|
||||||
|
path/filepath, internal/godebug < os/exec;
|
||||||
|
|
||||||
io/ioutil, os/exec, os/signal
|
io/ioutil, os/exec, os/signal
|
||||||
< OS;
|
< OS;
|
||||||
|
|
@ -187,8 +191,6 @@ var depsRules = `
|
||||||
OS
|
OS
|
||||||
< golang.org/x/sys/cpu;
|
< golang.org/x/sys/cpu;
|
||||||
|
|
||||||
os < internal/godebug;
|
|
||||||
|
|
||||||
# FMT is OS (which includes string routines) plus reflect and fmt.
|
# FMT is OS (which includes string routines) plus reflect and fmt.
|
||||||
# It does not include package log, which should be avoided in core packages.
|
# It does not include package log, which should be avoided in core packages.
|
||||||
strconv, unicode
|
strconv, unicode
|
||||||
|
|
|
||||||
|
|
@ -56,40 +56,58 @@ func TestLookPath(t *testing.T) {
|
||||||
|
|
||||||
// Add "." to PATH so that exec.LookPath looks in the current directory on all systems.
|
// Add "." to PATH so that exec.LookPath looks in the current directory on all systems.
|
||||||
// And try to trick it with "../testdir" too.
|
// And try to trick it with "../testdir" too.
|
||||||
for _, dir := range []string{".", "../testdir"} {
|
for _, errdot := range []string{"1", "0"} {
|
||||||
t.Run(pathVar+"="+dir, func(t *testing.T) {
|
t.Run("GODEBUG=execerrdot="+errdot, func(t *testing.T) {
|
||||||
t.Setenv(pathVar, dir+string(filepath.ListSeparator)+origPath)
|
t.Setenv("GODEBUG", "execerrdot="+errdot)
|
||||||
good := dir + "/execabs-test"
|
for _, dir := range []string{".", "../testdir"} {
|
||||||
if found, err := LookPath(good); err != nil || !strings.HasPrefix(found, good) {
|
t.Run(pathVar+"="+dir, func(t *testing.T) {
|
||||||
t.Fatalf(`LookPath(%#q) = %#q, %v, want "%s...", nil`, good, found, err, good)
|
t.Setenv(pathVar, dir+string(filepath.ListSeparator)+origPath)
|
||||||
}
|
good := dir + "/execabs-test"
|
||||||
if runtime.GOOS == "windows" {
|
if found, err := LookPath(good); err != nil || !strings.HasPrefix(found, good) {
|
||||||
good = dir + `\execabs-test`
|
t.Fatalf(`LookPath(%#q) = %#q, %v, want "%s...", nil`, good, found, err, good)
|
||||||
if found, err := LookPath(good); err != nil || !strings.HasPrefix(found, good) {
|
}
|
||||||
t.Fatalf(`LookPath(%#q) = %#q, %v, want "%s...", nil`, good, found, err, good)
|
if runtime.GOOS == "windows" {
|
||||||
}
|
good = dir + `\execabs-test`
|
||||||
}
|
if found, err := LookPath(good); err != nil || !strings.HasPrefix(found, good) {
|
||||||
|
t.Fatalf(`LookPath(%#q) = %#q, %v, want "%s...", nil`, good, found, err, good)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := LookPath("execabs-test"); err == nil {
|
_, err := LookPath("execabs-test")
|
||||||
t.Fatalf("LookPath didn't fail when finding a non-relative path")
|
if errdot == "1" {
|
||||||
} else if !errors.Is(err, ErrDot) {
|
if err == nil {
|
||||||
t.Fatalf("LookPath returned unexpected error: want Is ErrDot, got %q", err)
|
t.Fatalf("LookPath didn't fail when finding a non-relative path")
|
||||||
}
|
} else if !errors.Is(err, ErrDot) {
|
||||||
|
t.Fatalf("LookPath returned unexpected error: want Is ErrDot, got %q", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("LookPath failed unexpectedly: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd := Command("execabs-test")
|
cmd := Command("execabs-test")
|
||||||
if cmd.Err == nil {
|
if errdot == "1" {
|
||||||
t.Fatalf("Command didn't fail when finding a non-relative path")
|
if cmd.Err == nil {
|
||||||
} else if !errors.Is(cmd.Err, ErrDot) {
|
t.Fatalf("Command didn't fail when finding a non-relative path")
|
||||||
t.Fatalf("Command returned unexpected error: want Is ErrDot, got %q", cmd.Err)
|
} else if !errors.Is(cmd.Err, ErrDot) {
|
||||||
}
|
t.Fatalf("Command returned unexpected error: want Is ErrDot, got %q", cmd.Err)
|
||||||
cmd.Err = nil
|
}
|
||||||
|
cmd.Err = nil
|
||||||
|
} else {
|
||||||
|
if cmd.Err != nil {
|
||||||
|
t.Fatalf("Command failed unexpectedly: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clearing cmd.Err should let the execution proceed,
|
// Clearing cmd.Err should let the execution proceed,
|
||||||
// and it should fail because it's not a valid binary.
|
// and it should fail because it's not a valid binary.
|
||||||
if err := cmd.Run(); err == nil {
|
if err := cmd.Run(); err == nil {
|
||||||
t.Fatalf("Run did not fail: expected exec error")
|
t.Fatalf("Run did not fail: expected exec error")
|
||||||
} else if errors.Is(err, ErrDot) {
|
} else if errors.Is(err, ErrDot) {
|
||||||
t.Fatalf("Run returned unexpected error ErrDot: want error like ENOEXEC: %q", err)
|
t.Fatalf("Run returned unexpected error ErrDot: want error like ENOEXEC: %q", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,11 @@
|
||||||
// log.Fatal(err)
|
// log.Fatal(err)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
// Setting the environment variable GODEBUG=execerrdot=0
|
||||||
|
// disables generation of ErrDot entirely, temporarily restoring the pre-Go 1.19
|
||||||
|
// behavior for programs that are unable to apply more targeted fixes.
|
||||||
|
// A future version of Go may remove support for this variable.
|
||||||
|
//
|
||||||
// Before adding such overrides, make sure you understand the
|
// Before adding such overrides, make sure you understand the
|
||||||
// security implications of doing so.
|
// security implications of doing so.
|
||||||
// See https://go.dev/blog/path-security for more information.
|
// See https://go.dev/blog/path-security for more information.
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package exec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"internal/godebug"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -53,7 +54,7 @@ func LookPath(file string) (string, error) {
|
||||||
for _, dir := range filepath.SplitList(path) {
|
for _, dir := range filepath.SplitList(path) {
|
||||||
path := filepath.Join(dir, file)
|
path := filepath.Join(dir, file)
|
||||||
if err := findExecutable(path); err == nil {
|
if err := findExecutable(path); err == nil {
|
||||||
if !filepath.IsAbs(path) {
|
if !filepath.IsAbs(path) && godebug.Get("execerrdot") != "0" {
|
||||||
return path, &Error{file, ErrDot}
|
return path, &Error{file, ErrDot}
|
||||||
}
|
}
|
||||||
return path, nil
|
return path, nil
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ package exec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"internal/godebug"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -56,7 +57,7 @@ func LookPath(file string) (string, error) {
|
||||||
}
|
}
|
||||||
path := filepath.Join(dir, file)
|
path := filepath.Join(dir, file)
|
||||||
if err := findExecutable(path); err == nil {
|
if err := findExecutable(path); err == nil {
|
||||||
if !filepath.IsAbs(path) {
|
if !filepath.IsAbs(path) && godebug.Get("execerrdot") != "0" {
|
||||||
return path, &Error{file, ErrDot}
|
return path, &Error{file, ErrDot}
|
||||||
}
|
}
|
||||||
return path, nil
|
return path, nil
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package exec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"internal/godebug"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -102,6 +103,9 @@ func LookPath(file string) (string, error) {
|
||||||
)
|
)
|
||||||
if _, found := syscall.Getenv("NoDefaultCurrentDirectoryInExePath"); !found {
|
if _, found := syscall.Getenv("NoDefaultCurrentDirectoryInExePath"); !found {
|
||||||
if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
|
if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
|
||||||
|
if godebug.Get("execerrdot") == "0" {
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
dotf, dotErr = f, &Error{file, ErrDot}
|
dotf, dotErr = f, &Error{file, ErrDot}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +128,7 @@ func LookPath(file string) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !filepath.IsAbs(f) {
|
if !filepath.IsAbs(f) && godebug.Get("execerrdot") != "0" {
|
||||||
return f, &Error{file, ErrDot}
|
return f, &Error{file, ErrDot}
|
||||||
}
|
}
|
||||||
return f, nil
|
return f, nil
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue