From 492c85ab84dc1d4d19be0466d2d73f4a6174f07e Mon Sep 17 00:00:00 2001 From: Filippo Rossi Date: Mon, 4 Apr 2022 06:25:32 +0000 Subject: [PATCH] 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: 77fffa7635052f11dc93488ee23fd1c895284b4d GitHub-Pull-Request: golang/go#51845 Reviewed-on: https://go-review.googlesource.com/c/go/+/394154 Trust: Bryan Mills Reviewed-by: Bryan Mills Trust: Emmanuel Odeke Run-TryBot: Emmanuel Odeke TryBot-Result: Gopher Robot --- src/cmd/go/internal/workcmd/use.go | 31 +++++++++++++------ src/cmd/go/testdata/script/work_use_file.txt | 12 ------- .../go/testdata/script/work_use_only_dirs.txt | 17 ++++++++++ 3 files changed, 38 insertions(+), 22 deletions(-) delete mode 100644 src/cmd/go/testdata/script/work_use_file.txt create mode 100644 src/cmd/go/testdata/script/work_use_only_dirs.txt diff --git a/src/cmd/go/internal/workcmd/use.go b/src/cmd/go/internal/workcmd/use.go index 07bc9b0500..6da64b3f09 100644 --- a/src/cmd/go/internal/workcmd/use.go +++ b/src/cmd/go/internal/workcmd/use.go @@ -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 { diff --git a/src/cmd/go/testdata/script/work_use_file.txt b/src/cmd/go/testdata/script/work_use_file.txt deleted file mode 100644 index 807dd96c72..0000000000 --- a/src/cmd/go/testdata/script/work_use_file.txt +++ /dev/null @@ -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 -- diff --git a/src/cmd/go/testdata/script/work_use_only_dirs.txt b/src/cmd/go/testdata/script/work_use_only_dirs.txt new file mode 100644 index 0000000000..aa6dd78a6a --- /dev/null +++ b/src/cmd/go/testdata/script/work_use_only_dirs.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 \ No newline at end of file -- 2.48.1