94 lines
2.2 KiB
Go
94 lines
2.2 KiB
Go
package files
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNormalizeRelativeDirAllowsRootAndPreservesCase(t *testing.T) {
|
|
got, err := NormalizeRelativeDir("")
|
|
if err != nil {
|
|
t.Fatalf("NormalizeRelativeDir root: %v", err)
|
|
}
|
|
if got != "" {
|
|
t.Fatalf("root dir = %q, want empty", got)
|
|
}
|
|
|
|
got, err = NormalizeRelativeDir("Notes/Overview.md")
|
|
if err != nil {
|
|
t.Fatalf("NormalizeRelativeDir preserves case: %v", err)
|
|
}
|
|
if got != "Notes/Overview.md" {
|
|
t.Fatalf("path = %q, want Notes/Overview.md", got)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeRelativeFileRejectsUnsafePaths(t *testing.T) {
|
|
cases := []string{
|
|
"",
|
|
"/etc/passwd",
|
|
"C:\\Users\\file.txt",
|
|
"C:/Windows/system.ini",
|
|
`\\server\share`,
|
|
"//server/share",
|
|
`..\secret`,
|
|
`folder\..\secret`,
|
|
"../outside.txt",
|
|
"folder/../../outside.txt",
|
|
`folder\sub/../../secret`,
|
|
`folder\sub`,
|
|
"bad\x00name.txt",
|
|
".verstak",
|
|
".verstak/",
|
|
".verstak/vault.json",
|
|
"./.verstak",
|
|
".verstak/trash",
|
|
"folder/../.verstak",
|
|
".Verstak",
|
|
}
|
|
|
|
for _, input := range cases {
|
|
t.Run(input, func(t *testing.T) {
|
|
_, err := NormalizeRelativeFile(input)
|
|
if err == nil {
|
|
t.Fatalf("NormalizeRelativeFile(%q): expected error", input)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReservedPathPolicy(t *testing.T) {
|
|
if !IsReservedPath(".verstak") {
|
|
t.Fatal(".verstak should be reserved")
|
|
}
|
|
if !IsReservedPath(".verstak/trash/file.txt") {
|
|
t.Fatal(".verstak/trash/file.txt should be reserved")
|
|
}
|
|
if !IsReservedPath(".Verstak/trash/file.txt") {
|
|
t.Fatal(".Verstak/trash/file.txt should be reserved by case-insensitive policy")
|
|
}
|
|
if IsReservedPath("Notes/.verstak.md") {
|
|
t.Fatal("Notes/.verstak.md should not be reserved")
|
|
}
|
|
}
|
|
|
|
func TestNormalizeRelativeFileAcceptsOnlySlashSeparatedRelativePaths(t *testing.T) {
|
|
got, err := NormalizeRelativeFile("Notes/Overview.md")
|
|
if err != nil {
|
|
t.Fatalf("NormalizeRelativeFile valid slash path: %v", err)
|
|
}
|
|
if got != "Notes/Overview.md" {
|
|
t.Fatalf("path = %q, want Notes/Overview.md", got)
|
|
}
|
|
}
|
|
|
|
func TestPathPolicyErrorsAreReadable(t *testing.T) {
|
|
_, err := NormalizeRelativeFile("../outside.txt")
|
|
if err == nil {
|
|
t.Fatal("expected traversal error")
|
|
}
|
|
if !strings.Contains(err.Error(), "path-traversal") {
|
|
t.Fatalf("error = %q, want path-traversal", err.Error())
|
|
}
|
|
}
|