1
0
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:
Alex Brainman 2015-12-14 10:33:56 +11:00 committed by Russ Cox
parent cf49b35bd0
commit 61eb7058d0
3 changed files with 90 additions and 11 deletions

View File

@ -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{

View File

@ -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
}

View File

@ -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