Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion pkg/util/utilfn/utilfn.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,10 +617,37 @@ func CopyToChannel(outputCh chan<- []byte, reader io.Reader) error {
}
}

const (
winFlagSoftlink = uint32(0x8000) // FILE_ATTRIBUTE_REPARSE_POINT
winFlagJunction = uint32(0x80) // FILE_ATTRIBUTE_JUNCTION
)

func WinSymlinkDir(path string, bits os.FileMode) bool {
// Windows compatibility layer doesn't expose symlink target type through fileInfo
// so we need to check file attributes and extension patterns
isFileSymlink := func(filepath string) bool {
if len(filepath) == 0 {
return false
}
return strings.LastIndex(filepath, ".") > strings.LastIndex(filepath, "/")
}

flags := uint32(bits >> 12)

if flags == winFlagSoftlink {
return !isFileSymlink(path)
} else if flags == winFlagJunction {
return true
} else {
return false
}
}

// on error just returns ""
// does not return "application/octet-stream" as this is considered a detection failure
// can pass an existing fileInfo to avoid re-statting the file
// falls back to text/plain for 0 byte files

func DetectMimeType(path string, fileInfo fs.FileInfo, extended bool) string {
if fileInfo == nil {
statRtn, err := os.Stat(path)
Expand All @@ -629,7 +656,8 @@ func DetectMimeType(path string, fileInfo fs.FileInfo, extended bool) string {
}
fileInfo = statRtn
}
if fileInfo.IsDir() {

if fileInfo.IsDir() || WinSymlinkDir(path, fileInfo.Mode()) {
return "directory"
}
if fileInfo.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
Expand Down
Loading