aboutsummaryrefslogtreecommitdiff
path: root/src/path/filepath
diff options
context:
space:
mode:
authorAlex Brainman <alex.brainman@gmail.com>2015-12-14 10:33:56 +1100
committerRuss Cox <rsc@golang.org>2015-12-14 17:21:16 +0000
commit61eb7058d0bd04fe4f616ddd011e0c0cb2eaa39d (patch)
tree1efb88636a4d12cb3bc7c58a21b9de2aefc8f759 /src/path/filepath
parentcf49b35bd000279137c353fbdc9c02610b67be27 (diff)
downloadgo-61eb7058d0bd04fe4f616ddd011e0c0cb2eaa39d.tar.xz
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>
Diffstat (limited to 'src/path/filepath')
-rw-r--r--src/path/filepath/path_test.go69
-rw-r--r--src/path/filepath/symlink.go25
-rw-r--r--src/path/filepath/symlink_windows.go7
3 files changed, 90 insertions, 11 deletions
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
index 201f4fa869..db604ba91f 100644
--- a/src/path/filepath/path_test.go
+++ b/src/path/filepath/path_test.go
@@ -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{
diff --git a/src/path/filepath/symlink.go b/src/path/filepath/symlink.go
index dc7e9eb9bf..bc287c5ecb 100644
--- a/src/path/filepath/symlink.go
+++ b/src/path/filepath/symlink.go
@@ -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
}
diff --git a/src/path/filepath/symlink_windows.go b/src/path/filepath/symlink_windows.go
index 58288731aa..eb48367ec2 100644
--- a/src/path/filepath/symlink_windows.go
+++ b/src/path/filepath/symlink_windows.go
@@ -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