Repository: syncthing/syncthing
File: lib/fs/basicfs_lstat_windows.go (Go)

Code before:
func isDeduplicatedFile(reparseTag uint32) bool {
	return reparseTag == IO_REPARSE_TAG_DEDUP
}

type dirJunctFileInfo struct {
	os.FileInfo
}

func (fi *dirJunctFileInfo) Mode() os.FileMode {
	// Simulate a directory and not a symlink; also set the execute
	// bits so the directory can be traversed Unix-side.
	return fi.FileInfo.Mode() ^ os.ModeSymlink | os.ModeDir | 0111
}

func (fi *dirJunctFileInfo) IsDir() bool {
	return true
}

type dedupFileInfo struct {
	os.FileInfo
}

func (fi *dedupFileInfo) Mode() os.FileMode {
	// A deduplicated file should be treated as a regular file and not an
	// irregular file.
	return fi.FileInfo.Mode() ^ os.ModeIrregular
}

func (f *BasicFilesystem) underlyingLstat(name string) (os.FileInfo, error) {
	var fi, err = os.Lstat(name)

	// There are cases where files are tagged as symlink, but they end up being
	// something else. Make sure we properly handle those types.
	if err == nil {
		// NTFS directory junctions can be treated as ordinary directories,
		// see https://forum.syncthing.net/t/option-to-follow-directory-junctions-symbolic-links/14750
		if fi.Mode()&os.ModeSymlink != 0 && f.junctionsAsDirs {
			if reparseTag, reparseErr := readReparseTag(name); reparseErr == nil && isDirectoryJunction(reparseTag) {
				return &dirJunctFileInfo{fi}, nil
			}
		}

		// Workaround for #9120 till golang properly handles deduplicated files by
		// considering them regular files.
		if fi.Mode()&os.ModeIrregular != 0 {
			if reparseTag, reparseErr := readReparseTag(name); reparseErr == nil && isDeduplicatedFile(reparseTag) {
				return &dedupFileInfo{fi}, nil
			}
		}
	}


Review comment (suggestion):
```suggestion
	return fi.FileInfo.Mode() &^ os.ModeIrregular
```

should continue working if this bit becomes zero in the future

Code after:
func isDeduplicatedFile(reparseTag uint32) bool {
	return reparseTag == IO_REPARSE_TAG_DEDUP
}

type dirJunctFileInfo struct {
	os.FileInfo
}

func (fi *dirJunctFileInfo) Mode() os.FileMode {
	// Simulate a directory and not a symlink; also set the execute
	// bits so the directory can be traversed Unix-side.
	return fi.FileInfo.Mode() ^ os.ModeSymlink | os.ModeDir | 0111
}

func (fi *dirJunctFileInfo) IsDir() bool {
	return true
}

type dedupFileInfo struct {
	os.FileInfo
}

func (fi *dedupFileInfo) Mode() os.FileMode {
	// A deduplicated file should be treated as a regular file and not an
	// irregular file.
	return fi.FileInfo.Mode() &^ os.ModeIrregular
}

func (f *BasicFilesystem) underlyingLstat(name string) (os.FileInfo, error) {
	var fi, err = os.Lstat(name)

	// There are cases where files are tagged as symlink, but they end up being
	// something else. Make sure we properly handle those types.
	if err == nil {
		// NTFS directory junctions can be treated as ordinary directories,
		// see https://forum.syncthing.net/t/option-to-follow-directory-junctions-symbolic-links/14750
		if fi.Mode()&os.ModeSymlink != 0 && f.junctionsAsDirs {
			if reparseTag, reparseErr := readReparseTag(name); reparseErr == nil && isDirectoryJunction(reparseTag) {
				return &dirJunctFileInfo{fi}, nil
			}
		}

		// Workaround for #9120 till golang properly handles deduplicated files by
		// considering them regular files.
		if fi.Mode()&os.ModeIrregular != 0 {
			if reparseTag, reparseErr := readReparseTag(name); reparseErr == nil && isDeduplicatedFile(reparseTag) {
				return &dedupFileInfo{fi}, nil
			}
		}
	}