torrent/storage/safe-path.go

30 lines
871 B
Go

package storage
import (
"errors"
"path/filepath"
"strings"
)
// Get the first file path component. We can't use filepath.Split because that breaks off the last
// one. We could optimize this to avoid allocating a slice down the track.
func firstComponent(filePath string) string {
return strings.SplitN(filePath, string(filepath.Separator), 2)[0]
}
// Combines file info path components, ensuring the result won't escape into parent directories.
func ToSafeFilePath(fileInfoComponents ...string) (string, error) {
safeComps := make([]string, 0, len(fileInfoComponents))
for _, comp := range fileInfoComponents {
safeComps = append(safeComps, filepath.Clean(comp))
}
safeFilePath := filepath.Join(safeComps...)
fc := firstComponent(safeFilePath)
switch fc {
case "..":
return "", errors.New("escapes root dir")
default:
return safeFilePath, nil
}
}