Repository: syncthing/syncthing
File: lib/versioner/util.go (Go)

Code before:
				_, err := dstFs.Stat(folderPath[:i])
				if err == nil {
					continue
				}
				if !fs.IsNotExist(err) {
					return err
				}
			}
			hadParent = false
			err := dupDirWithPerms(srcFs, dstFs, folderPath[:i])
			if err != nil {
				return err
			}
		}
	}
	return dupDirWithPerms(srcFs, dstFs, folderPath)
}

func dupDirWithPerms(srcFs, dstFs fs.Filesystem, folderPath string) error {
	srcStat, err := srcFs.Stat(folderPath)
	if err != nil {
		return err
	}
	// If we call Mkdir with srcStat.Mode(), we won't get the expected perms because of umask
	// So, we create the folder with 0755, and then change the perms to the srcStat.Mode()
	err = dstFs.Mkdir(folderPath, 0o755)
	if err != nil {
		return err
	}
	return dstFs.Chmod(folderPath, srcStat.Mode())
}

func restoreFile(method fs.CopyRangeMethod, src, dst fs.Filesystem, filePath string, versionTime time.Time, tagger fileTagger) error {
	tag := versionTime.In(time.Local).Truncate(time.Second).Format(TimeFormat)
	taggedFilePath := tagger(filePath, tag)

	// If the something already exists where we are restoring to, archive existing file for versioning
	// remove if it's a symlink, or fail if it's a directory
	if info, err := dst.Lstat(filePath); err == nil {
		switch {
		case info.IsDir():
			return ErrDirectory
		case info.IsSymlink():
			// Remove existing symlinks (as we don't want to archive them)
			if err := dst.Remove(filePath); err != nil {
				return fmt.Errorf("removing existing symlink: %w", err)
			}
		case info.IsRegular():
			if err := archiveFile(method, dst, src, filePath, tagger); err != nil {
				return fmt.Errorf("archiving existing file: %w", err)
			}

Review comment (suggestion):
```suggestion
	// So, we create the folder with 0700, and then change the perms to the srcStat.Mode()
	err = dstFs.Mkdir(folderPath, 0o700)
```

avoids having (possibly) overly permissive bits for a while

Code after:
				_, err := dstFs.Stat(folderPath[:i])
				if err == nil {
					continue
				}
				if !fs.IsNotExist(err) {
					return err
				}
			}
			hadParent = false
			err := dupDirWithPerms(srcFs, dstFs, folderPath[:i])
			if err != nil {
				return err
			}
		}
	}
	return dupDirWithPerms(srcFs, dstFs, folderPath)
}

func dupDirWithPerms(srcFs, dstFs fs.Filesystem, folderPath string) error {
	srcStat, err := srcFs.Stat(folderPath)
	if err != nil {
		return err
	}
	// If we call Mkdir with srcStat.Mode(), we won't get the expected perms because of umask
	// So, we create the folder with 0700, and then change the perms to the srcStat.Mode()
	err = dstFs.Mkdir(folderPath, 0o700)
	if err != nil {
		return err
	}
	return dstFs.Chmod(folderPath, srcStat.Mode())
}

func restoreFile(method fs.CopyRangeMethod, src, dst fs.Filesystem, filePath string, versionTime time.Time, tagger fileTagger) error {
	tag := versionTime.In(time.Local).Truncate(time.Second).Format(TimeFormat)
	taggedFilePath := tagger(filePath, tag)

	// If the something already exists where we are restoring to, archive existing file for versioning
	// remove if it's a symlink, or fail if it's a directory
	if info, err := dst.Lstat(filePath); err == nil {
		switch {
		case info.IsDir():
			return ErrDirectory
		case info.IsSymlink():
			// Remove existing symlinks (as we don't want to archive them)
			if err := dst.Remove(filePath); err != nil {
				return fmt.Errorf("removing existing symlink: %w", err)
			}
		case info.IsRegular():
			if err := archiveFile(method, dst, src, filePath, tagger); err != nil {
				return fmt.Errorf("archiving existing file: %w", err)
			}