What version of Go are you using (go version)?
$ go version
go version devel go1.21-ebc13fb0b8 Wed Apr 12 16:09:24 2023 +0000 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/gopher/Library/Caches/go-build"
GOENV="/Users/gopher/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/tmp/buildlet/gopath/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/tmp/buildlet/gopath"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/tmp/buildlet/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/tmp/buildlet/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="devel gomote.XXXXX"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/tmp/buildlet/go/src/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/wh/9yc0j5w50z97w3528z_7qvr40000gn/T/go-build1774834589=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
Extend path/filepath.TestWalkSymlinkRoot with the following test cases, inspired by cmd/go.TestScript/list_goroot_symlink:
diff --git i/src/path/filepath/path_test.go w/src/path/filepath/path_test.go
index cfc5cad863..4337bedda3 100644
--- i/src/path/filepath/path_test.go
+++ w/src/path/filepath/path_test.go
@@ -842,6 +842,16 @@ func TestWalkSymlinkRoot(t *testing.T) {
t.Fatal(err)
}
+ abslink := filepath.Join(td, "abslink")
+ if err := os.Symlink(dir, abslink); err != nil {
+ t.Fatal(err)
+ }
+
+ linklink := filepath.Join(td, "linklink")
+ if err := os.Symlink("link", linklink); err != nil {
+ t.Fatal(err)
+ }
+
// Per https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/basedefs/V1_chap04.html#tag_04_12:
// “A pathname that contains at least one non- <slash> character and that ends
// with one or more trailing <slash> characters shall not be resolved
@@ -868,6 +878,26 @@ func TestWalkSymlinkRoot(t *testing.T) {
root: link + string(filepath.Separator),
want: []string{link, filepath.Join(link, "foo")},
},
+ {
+ desc: "abs no slash",
+ root: abslink,
+ want: []string{abslink},
+ },
+ {
+ desc: "abs with slash",
+ root: abslink + string(filepath.Separator),
+ want: []string{abslink, filepath.Join(abslink, "foo")},
+ },
+ {
+ desc: "double link no slash",
+ root: linklink,
+ want: []string{linklink},
+ },
+ {
+ desc: "double link with slash",
+ root: linklink + string(filepath.Separator),
+ want: []string{linklink, filepath.Join(linklink, "foo")},
+ },
} {
tt := tt
t.Run(tt.desc, func(t *testing.T) {
What did you expect to see?
The additional tests should pass.
Per POSIX pathname resolution, pathname resolution should proceed as:
- Any symlinks in the portion of the path in the
td variable are resolved, giving a path of the form $td/linklink/ (where $td is fully-resolved).
- The “remaining pathname” after the
linklink component is /.
$td/linklink resolves to $td/link, so $td/link should be prefixed to /, giving $td/link/ for the next step.
- Since the pathname
$td/link/ has a trailing slash and the path includes unresolved components, pathname resolution is not yet complete.
$td/link resolves to $td/dir, so $td/dir should be prefixed to /, giving $td/dir/, which is fully resolved.
What did you see instead?
The additional tests pass on linux, consistent with POSIX pathname resolution.
However, the linklink test fails on a darwin-amd64-longtest gomote instance:
--- FAIL: TestWalkSymlinkRoot (0.00s)
--- FAIL: TestWalkSymlinkRoot/double_link_with_slash (0.00s)
path_test.go:909: `/var/folders/wh/9yc0j5w50z97w3528z_7qvr40000gn/T/TestWalkSymlinkRoot3176243506/001/linklink/`: Lrwxr-xr-x
path_test.go:918: Walk(`/var/folders/wh/9yc0j5w50z97w3528z_7qvr40000gn/T/TestWalkSymlinkRoot3176243506/001/linklink/`) visited [`/var/folders/wh/9yc0j5w50z97w3528z_7qvr40000gn/T/TestWalkSymlinkRoot3176243506/001/linklink`]; want [`/var/folders/wh/9yc0j5w50z97w3528z_7qvr40000gn/T/TestWalkSymlinkRoot3176243506/001/linklink` `/var/folders/wh/9yc0j5w50z97w3528z_7qvr40000gn/T/TestWalkSymlinkRoot3176243506/001/linklink/foo`]
FAIL
FAIL path/filepath 0.104s
(CC @golang/darwin)
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env)?go envOutputWhat did you do?
Extend
path/filepath.TestWalkSymlinkRootwith the following test cases, inspired bycmd/go.TestScript/list_goroot_symlink:What did you expect to see?
The additional tests should pass.
Per POSIX pathname resolution, pathname resolution should proceed as:
tdvariable are resolved, giving a path of the form$td/linklink/(where$tdis fully-resolved).linklinkcomponent is/.$td/linklinkresolves to$td/link, so$td/linkshould be prefixed to/, giving$td/link/for the next step.$td/link/has a trailing slash and the path includes unresolved components, pathname resolution is not yet complete.$td/linkresolves to$td/dir, so$td/dirshould be prefixed to/, giving$td/dir/, which is fully resolved.What did you see instead?
The additional tests pass on
linux, consistent with POSIX pathname resolution.However, the
linklinktest fails on adarwin-amd64-longtestgomote instance:(CC @golang/darwin)