os: do not report ModeDir for symlinks on windows
When using Lstat against symlinks that point to a directory,
the function returns FileInfo with both ModeDir and ModeSymlink set.
Change that to never set ModeDir if ModeSymlink is set.
Fixes #10424
Fixes #17540
Fixes #17541
Change-Id: Iba280888aad108360b8c1f18180a24493fe7ad2b
Reviewed-on: https://go-review.googlesource.com/41830
Reviewed-by: Daniel Martà <mvdan@mvdan.cc>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Daniel Martà <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/archive/tar/tar_test.go b/src/archive/tar/tar_test.go
index 10a16dd..1cb7ec2 100644
--- a/src/archive/tar/tar_test.go
+++ b/src/archive/tar/tar_test.go
@@ -12,7 +12,6 @@
"path"
"path/filepath"
"reflect"
- "runtime"
"strings"
"testing"
"time"
@@ -72,9 +71,6 @@
func TestFileInfoHeaderSymlink(t *testing.T) {
testenv.MustHaveSymlink(t)
- if runtime.GOOS == "windows" {
- t.Skip("skipping broken test: see issue 17541")
- }
tmpdir, err := ioutil.TempDir("", "TestFileInfoHeaderSymlink")
if err != nil {
t.Fatal(err)
diff --git a/src/os/os_windows_test.go b/src/os/os_windows_test.go
index 3e82f69..84066de 100644
--- a/src/os/os_windows_test.go
+++ b/src/os/os_windows_test.go
@@ -153,6 +153,20 @@
t.Errorf("%q should point to %q", link, dir)
continue
}
+
+ fi2, err := os.Lstat(link)
+ if err != nil {
+ t.Errorf("failed to lstat link %v: %v", link, err)
+ continue
+ }
+ if m := fi2.Mode(); m&os.ModeSymlink == 0 {
+ t.Errorf("%q should be a link, but is not (mode=0x%x)", link, uint32(m))
+ continue
+ }
+ if m := fi2.Mode(); m&os.ModeDir != 0 {
+ t.Errorf("%q should be a link, not a directory (mode=0x%x)", link, uint32(m))
+ continue
+ }
}
}
diff --git a/src/os/types_windows.go b/src/os/types_windows.go
index 772b9e5..a0d6fa4 100644
--- a/src/os/types_windows.go
+++ b/src/os/types_windows.go
@@ -32,16 +32,16 @@
if fs == &devNullStat {
return ModeDevice | ModeCharDevice | 0666
}
- if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- m |= ModeDir | 0111
- }
if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 {
m |= 0444
} else {
m |= 0666
}
if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
- m |= ModeSymlink
+ return m | ModeSymlink
+ }
+ if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
+ m |= ModeDir | 0111
}
switch fs.filetype {
case syscall.FILE_TYPE_PIPE:
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
index d2a78f5..315f61e 100644
--- a/src/path/filepath/path_test.go
+++ b/src/path/filepath/path_test.go
@@ -1377,8 +1377,5 @@
func TestWalkSymlink(t *testing.T) {
testenv.MustHaveSymlink(t)
- if runtime.GOOS == "windows" {
- t.Skip("skipping broken test: see issue 17540")
- }
testWalkSymlink(t, os.Symlink)
}
diff --git a/src/path/filepath/path_windows_test.go b/src/path/filepath/path_windows_test.go
index 0663778..d759a83 100644
--- a/src/path/filepath/path_windows_test.go
+++ b/src/path/filepath/path_windows_test.go
@@ -451,12 +451,10 @@
func TestWalkDirectoryJunction(t *testing.T) {
testenv.MustHaveSymlink(t)
- t.Skip("skipping broken test: see issue 10424")
testWalkMklink(t, "J")
}
func TestWalkDirectorySymlink(t *testing.T) {
testenv.MustHaveSymlink(t)
- t.Skip("skipping broken test: see issue 17540")
testWalkMklink(t, "D")
}