internal/fastwalk: fix checkptr failure on Darwin
Darwin's syscall.Dirent is declared as larger than the kernel may
actually return. Don't assume that we can copy the whole thing out of a
buffer.
Fixes golang/go#37269
Change-Id: I7f2b273f3a14071df8b5ff5bd70e59d784f6d187
Reviewed-on: https://go-review.googlesource.com/c/tools/+/221381
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/internal/fastwalk/fastwalk_unix.go b/internal/fastwalk/fastwalk_unix.go
index ce38fdc..5901a8f 100644
--- a/internal/fastwalk/fastwalk_unix.go
+++ b/internal/fastwalk/fastwalk_unix.go
@@ -76,8 +76,9 @@
}
func parseDirEnt(buf []byte) (consumed int, name string, typ os.FileMode) {
- // golang.org/issue/15653
- dirent := (*syscall.Dirent)(unsafe.Pointer(&buf[0]))
+ // golang.org/issue/37269
+ dirent := &syscall.Dirent{}
+ copy((*[unsafe.Sizeof(syscall.Dirent{})]byte)(unsafe.Pointer(dirent))[:], buf)
if v := unsafe.Offsetof(dirent.Reclen) + unsafe.Sizeof(dirent.Reclen); uintptr(len(buf)) < v {
panic(fmt.Sprintf("buf size of %d smaller than dirent header size %d", len(buf), v))
}