1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
package admin
import (
"path/filepath"
"testing"
)
// TestResolveRoomSubdirRejectsEscape covers the traversal guard used by the
// room-directory API handlers (rename dir, move room, create empty room, bulk
// edit). Every escaping form must be rejected.
func TestResolveRoomSubdirRejectsEscape(t *testing.T) {
s := &AdminServer{dataDir: t.TempDir()}
for _, bad := range []string{"..", "../items", "../../etc", "/etc", "a/../../b", `..\items`, "town/../../x"} {
if _, err := s.resolveRoomSubdir(bad); err == nil {
t.Fatalf("accepted escaping dir %q", bad)
}
}
for _, ok := range []string{"", ".", "town", "town/sub"} {
got, err := s.resolveRoomSubdir(ok)
if err != nil {
t.Fatalf("rejected valid dir %q: %v", ok, err)
}
if ok != "" && ok != "." && got != filepath.FromSlash(ok) {
t.Fatalf("dir %q resolved to %q", ok, got)
}
}
}
// TestUndoHistorySurvivesReload: the editor documents that undo history is
// persisted across sessions; NewUndoStack must load what save wrote.
func TestUndoHistorySurvivesReload(t *testing.T) {
dir := t.TempDir()
us := NewUndoStack(dir)
us.Push(ChangeDesc{
Description: "edit x",
FilePath: filepath.Join(dir, "x.yaml"),
OldContent: []byte("old"),
NewContent: []byte("new"),
})
reloaded := NewUndoStack(dir)
info := reloaded.Info()
if !info.CanUndo || info.StackSize != 1 {
t.Fatalf("history did not survive reload: %+v", info)
}
if info.UndoDesc == "" {
t.Fatal("undo description empty after reload")
}
}
|