github.com/anacrolix/torrent@v1.61.0/storage/safe-path.go (about) 1 package storage 2 3 import ( 4 "errors" 5 "path/filepath" 6 "strings" 7 ) 8 9 // Get the first file path component. We can't use filepath.Split because that breaks off the last 10 // one. We could optimize this to avoid allocating a slice down the track. 11 func firstComponent(filePath string) string { 12 return strings.SplitN(filePath, string(filepath.Separator), 2)[0] 13 } 14 15 // Combines file info path components, ensuring the result won't escape into parent directories. 16 func ToSafeFilePath(fileInfoComponents ...string) (string, error) { 17 safeComps := make([]string, 0, len(fileInfoComponents)) 18 for _, comp := range fileInfoComponents { 19 safeComps = append(safeComps, filepath.Clean(comp)) 20 } 21 safeFilePath := filepath.Join(safeComps...) 22 fc := firstComponent(safeFilePath) 23 switch fc { 24 case "..": 25 return "", errors.New("escapes root dir") 26 default: 27 return safeFilePath, nil 28 } 29 }