From: Hiroshi Ioka Date: Fri, 7 Apr 2017 11:32:46 +0000 (+0900) Subject: os: handle relative symlinks correctly in Stat on windows X-Git-Tag: go1.9beta1~769 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=87bd0b2f142283ce3ee49d06074728b0ca900819;p=gostls13.git os: handle relative symlinks correctly in Stat on windows Walk relative symlinks in windows os.Stat from symlink path instead of from current directory. Fixes #19870 Change-Id: I0a27473d11485f073084b1f19b30c5b3a2fbc0f7 Reviewed-on: https://go-review.googlesource.com/39932 Reviewed-by: Alex Brainman Run-TryBot: Alex Brainman TryBot-Result: Gobot Gobot --- diff --git a/src/os/os_test.go b/src/os/os_test.go index a88ba54821..ee9e0cf767 100644 --- a/src/os/os_test.go +++ b/src/os/os_test.go @@ -1705,6 +1705,43 @@ func TestStatStdin(t *testing.T) { } } +func TestStatRelativeSymlink(t *testing.T) { + testenv.MustHaveSymlink(t) + + tmpdir, err := ioutil.TempDir("", "TestStatRelativeSymlink") + if err != nil { + t.Fatal(err) + } + defer RemoveAll(tmpdir) + + target := filepath.Join(tmpdir, "target") + f, err := Create(target) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + st, err := f.Stat() + if err != nil { + t.Fatal(err) + } + + link := filepath.Join(tmpdir, "link") + err = Symlink(filepath.Base(target), link) + if err != nil { + t.Fatal(err) + } + + st1, err := Stat(link) + if err != nil { + t.Fatal(err) + } + + if !SameFile(st, st1) { + t.Error("Stat doesn't follow relative symlink") + } +} + func TestReadAtEOF(t *testing.T) { f := newFile("TestReadAtEOF", t) defer Remove(f.Name()) diff --git a/src/os/stat_windows.go b/src/os/stat_windows.go index 0b8132f5c8..fe0ca8d1b2 100644 --- a/src/os/stat_windows.go +++ b/src/os/stat_windows.go @@ -71,10 +71,15 @@ func Stat(name string) (FileInfo, error) { if fi.Mode()&ModeSymlink == 0 { return fi, nil } - name, err = Readlink(name) + newname, err := Readlink(name) if err != nil { return fi, err } + if isAbs(newname) { + name = newname + } else { + name = dirname(name) + `\` + newname + } } return nil, &PathError{"Stat", name, syscall.ELOOP} }