]> Sergey Matveev's repositories - btrtrc.git/blob - storage/safe-path.go
Drop support for go 1.20
[btrtrc.git] / storage / safe-path.go
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 }