all: Adjust windows perms in fs package (#5200)

This commit is contained in:
Simon Frei 2018-09-16 16:09:56 +02:00 committed by GitHub
parent 60eb9088ff
commit 272fb3b444
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 51 deletions

View File

@ -8,8 +8,28 @@ package fs
import (
"os"
"path/filepath"
"strings"
)
var execExts map[string]bool
func init() {
// PATHEXT contains a list of executable file extensions, on Windows
pathext := filepath.SplitList(os.Getenv("PATHEXT"))
// We want the extensions in execExts to be lower case
execExts = make(map[string]bool, len(pathext))
for _, ext := range pathext {
execExts[strings.ToLower(ext)] = true
}
}
// isWindowsExecutable returns true if the given path has an extension that is
// in the list of executable extensions.
func isWindowsExecutable(path string) bool {
return execExts[strings.ToLower(filepath.Ext(path))]
}
func (e fsFileInfo) Mode() FileMode {
m := e.FileInfo.Mode()
if m&os.ModeSymlink != 0 && e.Size() > 0 {
@ -17,5 +37,14 @@ func (e fsFileInfo) Mode() FileMode {
// NTFS deduped files. Remove the symlink bit.
m &^= os.ModeSymlink
}
// Set executable bits on files with executable extenions (.exe, .bat, etc).
if isWindowsExecutable(e.Name()) {
m |= 0111
}
// There is no user/group/others in Windows' read-only attribute, and
// all "w" bits are set if the file is not read-only. Do not send these
// group/others-writable bits to other devices in order to avoid
// unexpected world-writable files on other platforms.
m &^= 0022
return FileMode(m)
}

View File

@ -1453,9 +1453,6 @@ func (f *sendReceiveFolder) performFinish(ignores *ignore.Matcher, file, curFile
// handle that.
curMode := uint32(stat.Mode())
if runtime.GOOS == "windows" && osutil.IsWindowsExecutable(file.Name) {
curMode |= 0111
}
// Check that the file on disk is what we expect it to be according
// to the database. If there's a mismatch here, there might be local

View File

@ -10,7 +10,6 @@ package osutil
import (
"errors"
"io"
"os"
"path/filepath"
"runtime"
"strings"
@ -136,24 +135,6 @@ func copyFileContents(filesystem fs.Filesystem, src, dst string) (err error) {
return
}
var execExts map[string]bool
func init() {
// PATHEXT contains a list of executable file extensions, on Windows
pathext := filepath.SplitList(os.Getenv("PATHEXT"))
// We want the extensions in execExts to be lower case
execExts = make(map[string]bool, len(pathext))
for _, ext := range pathext {
execExts[strings.ToLower(ext)] = true
}
}
// IsWindowsExecutable returns true if the given path has an extension that is
// in the list of executable extensions.
func IsWindowsExecutable(path string) bool {
return execExts[strings.ToLower(filepath.Ext(path))]
}
func IsDeleted(ffs fs.Filesystem, name string) bool {
if _, err := ffs.Lstat(name); fs.IsNotExist(err) {
return true

View File

@ -19,26 +19,10 @@ import (
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/ignore"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/protocol"
"golang.org/x/text/unicode/norm"
)
var maskModePerm fs.FileMode
func init() {
if runtime.GOOS == "windows" {
// There is no user/group/others in Windows' read-only
// attribute, and all "w" bits are set in fs.FileMode
// if the file is not read-only. Do not send these
// group/others-writable bits to other devices in order to
// avoid unexpected world-writable files on other platforms.
maskModePerm = fs.ModePerm & 0755
} else {
maskModePerm = fs.ModePerm
}
}
type Config struct {
// Folder for which the walker has been created
Folder string
@ -326,16 +310,10 @@ func (w *walker) walkRegular(ctx context.Context, relPath string, info fs.FileIn
curFile, hasCurFile := w.CurrentFiler.CurrentFile(relPath)
newMode := uint32(info.Mode())
if runtime.GOOS == "windows" {
if osutil.IsWindowsExecutable(relPath) {
// Set executable bits on files with executable extenions (.exe,
// .bat, etc).
newMode |= 0111
} else if hasCurFile {
// If we have an existing index entry, copy the executable bits
// from there.
newMode |= (curFile.Permissions & 0111)
}
if runtime.GOOS == "windows" && hasCurFile {
// If we have an existing index entry, copy the executable bits
// from there.
newMode |= (curFile.Permissions & 0111)
}
blockSize := protocol.MinBlockSize
@ -362,7 +340,7 @@ func (w *walker) walkRegular(ctx context.Context, relPath string, info fs.FileIn
Name: relPath,
Type: protocol.FileInfoTypeFile,
Version: curFile.Version.Update(w.ShortID),
Permissions: newMode & uint32(maskModePerm),
Permissions: newMode & uint32(fs.ModePerm),
NoPermissions: w.IgnorePerms,
ModifiedS: info.ModTime().Unix(),
ModifiedNs: int32(info.ModTime().Nanosecond()),
@ -405,7 +383,7 @@ func (w *walker) walkDir(ctx context.Context, relPath string, info fs.FileInfo,
Name: relPath,
Type: protocol.FileInfoTypeDirectory,
Version: cf.Version.Update(w.ShortID),
Permissions: uint32(info.Mode() & maskModePerm),
Permissions: uint32(info.Mode() & fs.ModePerm),
NoPermissions: w.IgnorePerms,
ModifiedS: info.ModTime().Unix(),
ModifiedNs: int32(info.ModTime().Nanosecond()),
@ -615,7 +593,7 @@ func CreateFileInfo(fi fs.FileInfo, name string, filesystem fs.Filesystem) (prot
f := protocol.FileInfo{
Name: name,
Type: protocol.FileInfoTypeFile,
Permissions: uint32(fi.Mode()),
Permissions: uint32(fi.Mode() & fs.ModePerm),
ModifiedS: fi.ModTime().Unix(),
ModifiedNs: int32(fi.ModTime().Nanosecond()),
Size: fi.Size(),