feat: whole bunch of shit
This commit is contained in:
56
server/internal/fsx/path.go
Normal file
56
server/internal/fsx/path.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package fsx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CleanURLLike(p string) string {
|
||||
p = strings.TrimSpace(p)
|
||||
if p == "" || p == "/" {
|
||||
return "/"
|
||||
}
|
||||
parts := []string{}
|
||||
for _, seg := range strings.Split(strings.ReplaceAll(p, "\\", "/"), "/") {
|
||||
switch seg {
|
||||
case "", ".":
|
||||
continue
|
||||
case "..":
|
||||
if len(parts) > 0 {
|
||||
parts = parts[:len(parts)-1]
|
||||
}
|
||||
default:
|
||||
parts = append(parts, seg)
|
||||
}
|
||||
}
|
||||
return "/" + strings.Join(parts, "/")
|
||||
}
|
||||
|
||||
func SafeRel(root, requested string) (string, error) {
|
||||
s := CleanURLLike(requested)
|
||||
if strings.HasPrefix(s, "/") {
|
||||
s = strings.TrimPrefix(s, "/")
|
||||
}
|
||||
full := filepath.Join(root, filepath.FromSlash(s))
|
||||
rel, err := filepath.Rel(root, full)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if rel == "." {
|
||||
return "/", nil
|
||||
}
|
||||
sep := string(filepath.Separator)
|
||||
if strings.HasPrefix(rel, "..") || strings.Contains(rel, ".."+sep) {
|
||||
return "", errors.New("path escapes root")
|
||||
}
|
||||
return "/" + filepath.ToSlash(rel), nil
|
||||
}
|
||||
|
||||
func ResponsePath(root, full string) string {
|
||||
rel, err := filepath.Rel(root, full)
|
||||
if err != nil || rel == "." {
|
||||
return "/"
|
||||
}
|
||||
return "/" + filepath.ToSlash(rel)
|
||||
}
|
Reference in New Issue
Block a user