Initial implementation: package-updater v1 #1
@@ -0,0 +1,23 @@
|
|||||||
|
package discovery
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsInsideRoot reports whether path is the same as, or nested inside,
|
||||||
|
// root. Both are cleaned before comparison so trailing slashes, "."
|
||||||
|
// segments, and ".." escapes are handled. Prefix tricks like
|
||||||
|
// "/foo" vs "/foo-evil" are NOT considered inside.
|
||||||
|
func IsInsideRoot(root, path string) bool {
|
||||||
|
r := filepath.Clean(root)
|
||||||
|
p := filepath.Clean(path)
|
||||||
|
if p == r {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
rel, err := filepath.Rel(r, p)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !strings.HasPrefix(rel, "..")
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package discovery_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/shcizo/package-updater/internal/discovery"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIsInsideRoot(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
root string
|
||||||
|
path string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{"direct child", "/home/shcizo/self-hosted", "/home/shcizo/self-hosted/myapp", true},
|
||||||
|
{"nested", "/home/shcizo/self-hosted", "/home/shcizo/self-hosted/a/b/c", true},
|
||||||
|
{"root itself", "/home/shcizo/self-hosted", "/home/shcizo/self-hosted", true},
|
||||||
|
{"sibling", "/home/shcizo/self-hosted", "/home/shcizo/other", false},
|
||||||
|
{"parent", "/home/shcizo/self-hosted", "/home/shcizo", false},
|
||||||
|
{"unrelated", "/home/shcizo/self-hosted", "/etc/passwd", false},
|
||||||
|
{"prefix-trick", "/home/shcizo/self-hosted", "/home/shcizo/self-hosted-evil", false},
|
||||||
|
{"dotdot escape", "/home/shcizo/self-hosted", "/home/shcizo/self-hosted/../etc", false},
|
||||||
|
{"trailing slash root", "/home/shcizo/self-hosted/", "/home/shcizo/self-hosted/x", true},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
require.Equal(t, c.want, discovery.IsInsideRoot(c.root, c.path))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user