fix(windows): safer logic for parsing app exec links

This commit is contained in:
Jan De Dobbeleer 2022-02-08 20:20:30 +01:00 committed by Jan De Dobbeleer
parent 2046dcefeb
commit c7a446c081
3 changed files with 16 additions and 12 deletions

View file

@ -418,7 +418,8 @@ func (env *ShellEnvironment) HasCommand(command string) bool {
env.cmdCache.set(command, path)
return true
}
if path, err := env.LookWinAppPath(command); err == nil {
path, err = env.LookWinAppPath(command)
if err == nil {
env.cmdCache.set(command, path)
return true
}

View file

@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"syscall"
"time"
@ -117,13 +118,13 @@ func (env *ShellEnvironment) CachePath() string {
}
func (env *ShellEnvironment) LookWinAppPath(file string) (string, error) {
winAppPath := env.Home() + `\AppData\Local\Microsoft\WindowsApps\`
winAppPath := filepath.Join(env.Getenv("LOCALAPPDATA"), `\Microsoft\WindowsApps\`)
command := file + ".exe"
isWinStoreApp := func() bool {
return env.HasFilesInDir(winAppPath, command)
}
if isWinStoreApp() {
commandFile := winAppPath + command
commandFile := filepath.Join(winAppPath, command)
return readWinAppLink(commandFile)
}
return "", errors.New("no Windows Store App")

View file

@ -218,7 +218,7 @@ type AppExecLinkReparseBuffer struct {
StringList [1]uint16
}
func (rb *AppExecLinkReparseBuffer) Path() string {
func (rb *AppExecLinkReparseBuffer) Path() (string, error) {
UTF16ToStringPosition := func(s []uint16) (string, int) {
for i, v := range s {
if v == 0 {
@ -228,15 +228,18 @@ func (rb *AppExecLinkReparseBuffer) Path() string {
}
return "", 0
}
s := (*[0xffff]uint16)(unsafe.Pointer(&rb.StringList[0]))[0:]
stringList := (*[0xffff]uint16)(unsafe.Pointer(&rb.StringList[0]))[0:]
var link string
position := 0
var position int
for i := 0; i <= 2; i++ {
link, position = UTF16ToStringPosition(s)
link, position = UTF16ToStringPosition(stringList)
position++
s = s[position:]
if position >= len(stringList) {
return "", errors.New("invalid AppExecLinkReparseBuffer")
}
return link
stringList = stringList[position:]
}
return link, nil
}
// openSymlink calls CreateFile Windows API with FILE_FLAG_OPEN_REPARSE_POINT
@ -276,8 +279,7 @@ func readWinAppLink(path string) (string, error) {
rb := (*GenericDataBuffer)(unsafe.Pointer(&rdb.DUMMYUNIONNAME))
appExecLink := (*AppExecLinkReparseBuffer)(unsafe.Pointer(&rb.DataBuffer))
if appExecLink.Version != 3 {
return " ", errors.New("unknown appexec link version")
return " ", errors.New("unknown AppExecLink version")
}
link := appExecLink.Path()
return link, nil
return appExecLink.Path()
}