mirror of
https://github.com/golang/go
synced 2024-11-18 00:54:45 -07:00
path/filepath: keep walking if EvalSymlinks returns symlink
Fixes #13582 Change-Id: I220f3c7b9511b3c080874f5c42f2a431fdddcbb7 Reviewed-on: https://go-review.googlesource.com/17794 TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
cf49b35bd0
commit
61eb7058d0
@ -895,6 +895,75 @@ func TestEvalSymlinks(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue13582(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "android", "nacl", "plan9":
|
||||
t.Skipf("skipping on %s", runtime.GOOS)
|
||||
}
|
||||
if !supportsSymlinks {
|
||||
t.Skip("skipping because symlinks are not supported")
|
||||
}
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "issue13582")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
dir := filepath.Join(tmpDir, "dir")
|
||||
err = os.Mkdir(dir, 0755)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
linkToDir := filepath.Join(tmpDir, "link_to_dir")
|
||||
err = os.Symlink(dir, linkToDir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file := filepath.Join(linkToDir, "file")
|
||||
err = ioutil.WriteFile(file, nil, 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
link1 := filepath.Join(linkToDir, "link1")
|
||||
err = os.Symlink(file, link1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
link2 := filepath.Join(linkToDir, "link2")
|
||||
err = os.Symlink(link1, link2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// /tmp may itself be a symlink!
|
||||
realTmpDir, err := filepath.EvalSymlinks(tmpDir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
realDir := filepath.Join(realTmpDir, "dir")
|
||||
realFile := filepath.Join(realDir, "file")
|
||||
|
||||
tests := []struct {
|
||||
path, want string
|
||||
}{
|
||||
{dir, realDir},
|
||||
{linkToDir, realDir},
|
||||
{file, realFile},
|
||||
{link1, realFile},
|
||||
{link2, realFile},
|
||||
}
|
||||
for _, test := range tests {
|
||||
have, err := filepath.EvalSymlinks(test.path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if have != test.want {
|
||||
t.Errorf("EvalSymlinks(%q) returns %q, want %q", test.path, have, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test directories relative to temporary directory.
|
||||
// The tests are run in absTestDirs[0].
|
||||
var absTestDirs = []string{
|
||||
|
@ -85,7 +85,6 @@ func walkLinks(path string, linksWalked *int) (string, error) {
|
||||
return newpath, nil
|
||||
}
|
||||
return Join(newdir, newpath), nil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,9 +93,25 @@ func walkSymlinks(path string) (string, error) {
|
||||
return path, nil
|
||||
}
|
||||
var linksWalked int // to protect against cycles
|
||||
newpath, err := walkLinks(path, &linksWalked)
|
||||
if err != nil {
|
||||
return "", err
|
||||
for {
|
||||
i := linksWalked
|
||||
newpath, err := walkLinks(path, &linksWalked)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
// walkLinks(".", ...) always retuns "." on unix.
|
||||
// But on windows it returns symlink target, if current
|
||||
// directory is a symlink. Stop the walk, if symlink
|
||||
// target is not absolute path, and return "."
|
||||
// to the caller (just like unix does).
|
||||
if path == "." && !IsAbs(newpath) {
|
||||
return ".", nil
|
||||
}
|
||||
}
|
||||
if i == linksWalked {
|
||||
return Clean(newpath), nil
|
||||
}
|
||||
path = newpath
|
||||
}
|
||||
return Clean(newpath), nil
|
||||
}
|
||||
|
@ -47,15 +47,10 @@ func toLong(path string) (string, error) {
|
||||
}
|
||||
|
||||
func evalSymlinks(path string) (string, error) {
|
||||
newpath, err := walkSymlinks(path)
|
||||
path, err := walkSymlinks(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// discard the walk if path is "." and link destination is relative path (just like unix does)
|
||||
if path != "." || IsAbs(newpath) {
|
||||
path = newpath
|
||||
}
|
||||
|
||||
p, err := toShort(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
Loading…
Reference in New Issue
Block a user