mirror of
https://github.com/golang/go
synced 2024-11-05 16:26:11 -07:00
os: don't use a symlink's target path for FileInfo#Name on windows
Use an original name instead of a symlink's target path. Fixes #20064 Change-Id: I9be3837a156bdcda0e9e065abbb425d535b27be3 Reviewed-on: https://go-review.googlesource.com/41310 Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Run-TryBot: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
67399c6279
commit
94dd0f0227
@ -712,55 +712,58 @@ func TestSymlink(t *testing.T) {
|
||||
Remove(from) // Just in case.
|
||||
file, err := Create(to)
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", to, err)
|
||||
t.Fatalf("Create(%q) failed: %v", to, err)
|
||||
}
|
||||
defer Remove(to)
|
||||
if err = file.Close(); err != nil {
|
||||
t.Errorf("close %q failed: %v", to, err)
|
||||
t.Errorf("Close(%q) failed: %v", to, err)
|
||||
}
|
||||
err = Symlink(to, from)
|
||||
if err != nil {
|
||||
t.Fatalf("symlink %q, %q failed: %v", to, from, err)
|
||||
t.Fatalf("Symlink(%q, %q) failed: %v", to, from, err)
|
||||
}
|
||||
defer Remove(from)
|
||||
tostat, err := Lstat(to)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", to, err)
|
||||
t.Fatalf("Lstat(%q) failed: %v", to, err)
|
||||
}
|
||||
if tostat.Mode()&ModeSymlink != 0 {
|
||||
t.Fatalf("stat %q claims to have found a symlink", to)
|
||||
t.Fatalf("Lstat(%q).Mode()&ModeSymlink = %v, want 0", to, tostat.Mode()&ModeSymlink)
|
||||
}
|
||||
fromstat, err := Stat(from)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", from, err)
|
||||
t.Fatalf("Stat(%q) failed: %v", from, err)
|
||||
}
|
||||
if !SameFile(tostat, fromstat) {
|
||||
t.Errorf("symlink %q, %q did not create symlink", to, from)
|
||||
t.Errorf("Symlink(%q, %q) did not create symlink", to, from)
|
||||
}
|
||||
fromstat, err = Lstat(from)
|
||||
if err != nil {
|
||||
t.Fatalf("lstat %q failed: %v", from, err)
|
||||
t.Fatalf("Lstat(%q) failed: %v", from, err)
|
||||
}
|
||||
if fromstat.Mode()&ModeSymlink == 0 {
|
||||
t.Fatalf("symlink %q, %q did not create symlink", to, from)
|
||||
t.Fatalf("Lstat(%q).Mode()&ModeSymlink = 0, want %v", from, ModeSymlink)
|
||||
}
|
||||
fromstat, err = Stat(from)
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", from, err)
|
||||
t.Fatalf("Stat(%q) failed: %v", from, err)
|
||||
}
|
||||
if fromstat.Name() != from {
|
||||
t.Errorf("Stat(%q).Name() = %q, want %q", from, fromstat.Name(), from)
|
||||
}
|
||||
if fromstat.Mode()&ModeSymlink != 0 {
|
||||
t.Fatalf("stat %q did not follow symlink", from)
|
||||
t.Fatalf("Stat(%q).Mode()&ModeSymlink = %v, want 0", from, fromstat.Mode()&ModeSymlink)
|
||||
}
|
||||
s, err := Readlink(from)
|
||||
if err != nil {
|
||||
t.Fatalf("readlink %q failed: %v", from, err)
|
||||
t.Fatalf("Readlink(%q) failed: %v", from, err)
|
||||
}
|
||||
if s != to {
|
||||
t.Fatalf("after symlink %q != %q", s, to)
|
||||
t.Fatalf("Readlink(%q) = %q, want %q", from, s, to)
|
||||
}
|
||||
file, err = Open(from)
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", from, err)
|
||||
t.Fatalf("Open(%q) failed: %v", from, err)
|
||||
}
|
||||
file.Close()
|
||||
}
|
||||
|
@ -105,6 +105,10 @@ func testDirLinks(t *testing.T, tests []dirLinkTest) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fi, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("abc"), 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -113,7 +117,7 @@ func testDirLinks(t *testing.T, tests []dirLinkTest) {
|
||||
link := filepath.Join(tmpdir, test.name+"_link")
|
||||
err := test.mklink(link, dir)
|
||||
if err != nil {
|
||||
t.Errorf("creating link for %s test failed: %v", test.name, err)
|
||||
t.Errorf("creating link for %q test failed: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -132,15 +136,21 @@ func testDirLinks(t *testing.T, tests []dirLinkTest) {
|
||||
continue
|
||||
}
|
||||
|
||||
fi, err := os.Stat(link)
|
||||
fi1, err := os.Stat(link)
|
||||
if err != nil {
|
||||
t.Errorf("failed to stat link %v: %v", link, err)
|
||||
continue
|
||||
}
|
||||
expected := filepath.Base(dir)
|
||||
got := fi.Name()
|
||||
if !fi.IsDir() || expected != got {
|
||||
t.Errorf("link should point to %v but points to %v instead", expected, got)
|
||||
if !fi1.IsDir() {
|
||||
t.Errorf("%q should be a directory", link)
|
||||
continue
|
||||
}
|
||||
if fi1.Name() != filepath.Base(link) {
|
||||
t.Errorf("Stat(%q).Name() = %q, want %q", link, fi1.Name(), filepath.Base(link))
|
||||
continue
|
||||
}
|
||||
if !os.SameFile(fi, fi1) {
|
||||
t.Errorf("%q should point to %q", link, dir)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
@ -63,25 +63,27 @@ func (file *File) Stat() (FileInfo, error) {
|
||||
func Stat(name string) (FileInfo, error) {
|
||||
var fi FileInfo
|
||||
var err error
|
||||
link := name
|
||||
for i := 0; i < 255; i++ {
|
||||
fi, err = Lstat(name)
|
||||
fi, err = Lstat(link)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fi.Mode()&ModeSymlink == 0 {
|
||||
fi.(*fileStat).name = basename(name)
|
||||
return fi, nil
|
||||
}
|
||||
newname, err := Readlink(name)
|
||||
newlink, err := Readlink(link)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch {
|
||||
case isAbs(newname):
|
||||
name = newname
|
||||
case len(newname) > 0 && IsPathSeparator(newname[0]):
|
||||
name = volumeName(name) + newname
|
||||
case isAbs(newlink):
|
||||
link = newlink
|
||||
case len(newlink) > 0 && IsPathSeparator(newlink[0]):
|
||||
link = volumeName(link) + newlink
|
||||
default:
|
||||
name = dirname(name) + `\` + newname
|
||||
link = dirname(link) + `\` + newlink
|
||||
}
|
||||
}
|
||||
return nil, &PathError{"Stat", name, syscall.ELOOP}
|
||||
|
Loading…
Reference in New Issue
Block a user