stash
This commit is contained in:
29
safepath.go
Normal file
29
safepath.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// resolveSafe joins p onto root, cleans it, and confirms the result stays
|
||||
// within root. Rejects absolute paths and anything that escapes via "..".
|
||||
func resolveSafe(root, p string) (string, error) {
|
||||
if p == "" {
|
||||
return "", fmt.Errorf("empty path")
|
||||
}
|
||||
if filepath.IsAbs(p) {
|
||||
return "", fmt.Errorf("absolute paths are not allowed: %s", p)
|
||||
}
|
||||
joined := filepath.Join(root, p)
|
||||
cleaned := filepath.Clean(joined)
|
||||
|
||||
rel, err := filepath.Rel(root, cleaned)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot resolve %q: %w", p, err)
|
||||
}
|
||||
if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
|
||||
return "", fmt.Errorf("path escapes project root: %s", p)
|
||||
}
|
||||
return cleaned, nil
|
||||
}
|
||||
Reference in New Issue
Block a user