forked from anacrolix/torrent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
safe-path.go
29 lines (26 loc) · 871 Bytes
/
safe-path.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
}
}