aboutsummaryrefslogtreecommitdiff
path: root/internal/plan/hostile_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/plan/hostile_test.go')
-rw-r--r--internal/plan/hostile_test.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/internal/plan/hostile_test.go b/internal/plan/hostile_test.go
new file mode 100644
index 0000000..c22fb24
--- /dev/null
+++ b/internal/plan/hostile_test.go
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package plan
+
+import (
+ "fmt"
+ "testing"
+ "time"
+
+ "krino/internal/config"
+)
+
+// TestBuildRefusesDotNames: a rename whose placeholders produce "", "." or
+// ".." names a directory, not a file; the step is skipped with a reason
+// instead of renaming a file onto its own folder or the one above.
+func TestBuildRefusesDotNames(t *testing.T) {
+ for _, capture := range []string{"", ".", ".."} {
+ in := []Input{{
+ File: file("/r", "x.pdf"),
+ Rules: []RuleMatch{{Name: "a", Captures: []string{"x.pdf", capture}, Actions: []config.Action{act(config.Rename, "{1}")}}},
+ }}
+ c := Build("/r", in, time.Now(), NoDisk{}, NewClaims())[0]
+ if want := fmt.Sprintf("rename produced the name %q", capture); c.Steps[0].Skip != want {
+ t.Errorf("capture %q: Skip = %q, want %q", capture, c.Steps[0].Skip, want)
+ }
+ }
+}
+
+// TestBuildRefusesDotDotFromPlaceholder: a file name can capture "..",
+// though never "/", so a destination whose placeholders add a ".." segment
+// would leave the directory the rule names: that step is skipped. A ".."
+// the rule wrote itself is the rule's own business, and "..x" is a name,
+// not a segment.
+func TestBuildRefusesDotDotFromPlaceholder(t *testing.T) {
+ step := func(dest string) Step {
+ in := []Input{{
+ File: file("/r", "x.pdf"),
+ Rules: []RuleMatch{{Name: "a", Captures: []string{"x.pdf", ".."}, Actions: []config.Action{act(config.Move, dest)}}},
+ }}
+ return Build("/r", in, time.Now(), NoDisk{}, NewClaims())[0].Steps[0]
+ }
+ if s := step("/w/{1}/in"); s.Skip != `destination "/w/../in" leaves its directory through a placeholder` {
+ t.Errorf("placeholder ..: Skip = %q, Dst = %q", s.Skip, s.Dst)
+ }
+ if s := step("/w/../in"); s.Skip != "" || s.Dst != "/in/x.pdf" {
+ t.Errorf("written ..: Skip = %q, Dst = %q", s.Skip, s.Dst)
+ }
+ if s := step("/w/{1}x"); s.Skip != "" || s.Dst != "/w/..x/x.pdf" {
+ t.Errorf("..x: Skip = %q, Dst = %q", s.Skip, s.Dst)
+ }
+}