diff --git a/internal/fastwalk/fastwalk_dirent_namlen_linux.go b/internal/fastwalk/fastwalk_dirent_namlen_linux.go index 61896ffe7e..e880d358b1 100644 --- a/internal/fastwalk/fastwalk_dirent_namlen_linux.go +++ b/internal/fastwalk/fastwalk_dirent_namlen_linux.go @@ -16,7 +16,12 @@ import ( func direntNamlen(dirent *syscall.Dirent) uint64 { const fixedHdr = uint16(unsafe.Offsetof(syscall.Dirent{}.Name)) nameBuf := (*[unsafe.Sizeof(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0])) - nameLen := bytes.IndexByte(nameBuf[:dirent.Reclen-fixedHdr], 0) + const nameBufLen = uint16(len(nameBuf)) + limit := dirent.Reclen - fixedHdr + if limit > nameBufLen { + limit = nameBufLen + } + nameLen := bytes.IndexByte(nameBuf[:limit], 0) if nameLen < 0 { panic("failed to find terminating 0 byte in dirent") } diff --git a/internal/fastwalk/fastwalk_test.go b/internal/fastwalk/fastwalk_test.go index efb813c67a..a122ddf679 100644 --- a/internal/fastwalk/fastwalk_test.go +++ b/internal/fastwalk/fastwalk_test.go @@ -98,6 +98,23 @@ func TestFastWalk_Basic(t *testing.T) { }) } +func TestFastWalk_LongFileName(t *testing.T) { + longFileName := strings.Repeat("x", 255) + + testFastWalk(t, map[string]string{ + longFileName: "one", + }, + func(path string, typ os.FileMode) error { + return nil + }, + map[string]os.FileMode{ + "": os.ModeDir, + "/src": os.ModeDir, + "/src/" + longFileName: 0, + }, + ) +} + func TestFastWalk_Symlink(t *testing.T) { switch runtime.GOOS { case "windows", "plan9":