mirror of https://github.com/golang/go.git
cmd/go: prevent panic in go work use
Check if paths passed as arguments are existing directories.
Fixes #51841
Fixes #51749
Change-Id: Icfd148627e6f2c4651d6f923a37d413e68c67f6c
GitHub-Last-Rev: 77fffa7635
GitHub-Pull-Request: golang/go#51845
Reviewed-on: https://go-review.googlesource.com/c/go/+/394154
Trust: Bryan Mills <bcmills@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
884e75fa53
commit
492c85ab84
|
|
@ -12,7 +12,6 @@ import (
|
|||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/str"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
|
|
@ -109,17 +108,33 @@ func runUse(ctx context.Context, cmd *base.Command, args []string) {
|
|||
base.Fatalf("go: 'go work use' requires one or more directory arguments")
|
||||
}
|
||||
for _, useDir := range args {
|
||||
if !*useR {
|
||||
if target, err := fsys.Stat(useDir); err == nil && !target.IsDir() {
|
||||
base.Errorf(`go: argument "%s" is not a directory`, useDir)
|
||||
absArg, _ := pathRel(workDir, useDir)
|
||||
|
||||
info, err := fsys.Stat(absArg)
|
||||
if err != nil {
|
||||
// Errors raised from os.Stat are formatted to be more user-friendly.
|
||||
if os.IsNotExist(err) {
|
||||
base.Errorf("go: directory %v does not exist", absArg)
|
||||
} else {
|
||||
lookDir(useDir)
|
||||
base.Errorf("go: %v", err)
|
||||
}
|
||||
continue
|
||||
} else if !info.IsDir() {
|
||||
base.Errorf("go: %s is not a directory", absArg)
|
||||
continue
|
||||
}
|
||||
|
||||
if !*useR {
|
||||
lookDir(useDir)
|
||||
continue
|
||||
}
|
||||
|
||||
// Add or remove entries for any subdirectories that still exist.
|
||||
err := fsys.Walk(useDir, func(path string, info fs.FileInfo, err error) error {
|
||||
fsys.Walk(useDir, func(path string, info fs.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
if info.Mode()&fs.ModeSymlink != 0 {
|
||||
if target, err := fsys.Stat(path); err == nil && target.IsDir() {
|
||||
|
|
@ -131,13 +146,9 @@ func runUse(ctx context.Context, cmd *base.Command, args []string) {
|
|||
lookDir(path)
|
||||
return nil
|
||||
})
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
base.Errorf("go: %v", err)
|
||||
}
|
||||
|
||||
// Remove entries for subdirectories that no longer exist.
|
||||
// Because they don't exist, they will be skipped by Walk.
|
||||
absArg, _ := pathRel(workDir, useDir)
|
||||
for absDir, _ := range haveDirs {
|
||||
if str.HasFilePathPrefix(absDir, absArg) {
|
||||
if _, ok := keepDirs[absDir]; !ok {
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
cp go.work go.work.orig
|
||||
|
||||
# If an argument to 'go work use' is a file it should be handled gracefully as
|
||||
# an error and go.work should not be modified
|
||||
! go work use foo.txt
|
||||
stderr '^go: argument "foo\.txt" is not a directory$'
|
||||
cmp go.work go.work.orig
|
||||
|
||||
|
||||
-- go.work --
|
||||
go 1.18
|
||||
-- foo.txt --
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
! go work use foo bar baz
|
||||
|
||||
stderr '^go: '$WORK'[/\\]gopath[/\\]src[/\\]foo is not a directory'
|
||||
stderr '^go: directory '$WORK'[/\\]gopath[/\\]src[/\\]baz does not exist'
|
||||
cmp go.work go.work_want
|
||||
|
||||
! go work use -r qux
|
||||
stderr '^go: '$WORK'[/\\]gopath[/\\]src[/\\]qux is not a directory'
|
||||
|
||||
-- go.work --
|
||||
go 1.18
|
||||
-- go.work_want --
|
||||
go 1.18
|
||||
-- foo --
|
||||
-- qux --
|
||||
-- bar/go.mod --
|
||||
module bar
|
||||
Loading…
Reference in New Issue