Skip to content

Commit 492c85a

Browse files
Filippo Rossiodeke-em
Filippo Rossi
authored andcommitted
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: 77fffa7 GitHub-Pull-Request: #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>
1 parent 884e75f commit 492c85a

File tree

3 files changed

+38
-22
lines changed

3 files changed

+38
-22
lines changed

src/cmd/go/internal/workcmd/use.go

+21-10
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"cmd/go/internal/modload"
1313
"cmd/go/internal/str"
1414
"context"
15-
"errors"
1615
"fmt"
1716
"io/fs"
1817
"os"
@@ -109,17 +108,33 @@ func runUse(ctx context.Context, cmd *base.Command, args []string) {
109108
base.Fatalf("go: 'go work use' requires one or more directory arguments")
110109
}
111110
for _, useDir := range args {
112-
if !*useR {
113-
if target, err := fsys.Stat(useDir); err == nil && !target.IsDir() {
114-
base.Errorf(`go: argument "%s" is not a directory`, useDir)
111+
absArg, _ := pathRel(workDir, useDir)
112+
113+
info, err := fsys.Stat(absArg)
114+
if err != nil {
115+
// Errors raised from os.Stat are formatted to be more user-friendly.
116+
if os.IsNotExist(err) {
117+
base.Errorf("go: directory %v does not exist", absArg)
115118
} else {
116-
lookDir(useDir)
119+
base.Errorf("go: %v", err)
117120
}
118121
continue
122+
} else if !info.IsDir() {
123+
base.Errorf("go: %s is not a directory", absArg)
124+
continue
125+
}
126+
127+
if !*useR {
128+
lookDir(useDir)
129+
continue
119130
}
120131

121132
// Add or remove entries for any subdirectories that still exist.
122-
err := fsys.Walk(useDir, func(path string, info fs.FileInfo, err error) error {
133+
fsys.Walk(useDir, func(path string, info fs.FileInfo, err error) error {
134+
if err != nil {
135+
return err
136+
}
137+
123138
if !info.IsDir() {
124139
if info.Mode()&fs.ModeSymlink != 0 {
125140
if target, err := fsys.Stat(path); err == nil && target.IsDir() {
@@ -131,13 +146,9 @@ func runUse(ctx context.Context, cmd *base.Command, args []string) {
131146
lookDir(path)
132147
return nil
133148
})
134-
if err != nil && !errors.Is(err, os.ErrNotExist) {
135-
base.Errorf("go: %v", err)
136-
}
137149

138150
// Remove entries for subdirectories that no longer exist.
139151
// Because they don't exist, they will be skipped by Walk.
140-
absArg, _ := pathRel(workDir, useDir)
141152
for absDir, _ := range haveDirs {
142153
if str.HasFilePathPrefix(absDir, absArg) {
143154
if _, ok := keepDirs[absDir]; !ok {

src/cmd/go/testdata/script/work_use_file.txt

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
! go work use foo bar baz
2+
3+
stderr '^go: '$WORK'[/\\]gopath[/\\]src[/\\]foo is not a directory'
4+
stderr '^go: directory '$WORK'[/\\]gopath[/\\]src[/\\]baz does not exist'
5+
cmp go.work go.work_want
6+
7+
! go work use -r qux
8+
stderr '^go: '$WORK'[/\\]gopath[/\\]src[/\\]qux is not a directory'
9+
10+
-- go.work --
11+
go 1.18
12+
-- go.work_want --
13+
go 1.18
14+
-- foo --
15+
-- qux --
16+
-- bar/go.mod --
17+
module bar

0 commit comments

Comments
 (0)