//go:build linux package test import ( infraUpdate "RenewCMS/internal/infrastructure/update" "os" "path/filepath" "testing" ) func TestNoFollowFilesystemOnLinux(t *testing.T) { files := infraUpdate.NewNoFollowFilesystem() directory := t.TempDir() outside := filepath.Join(t.TempDir(), "outside.txt") if err := os.WriteFile(outside, []byte("sentinel"), 0o644); err != nil { t.Fatal(err) } link := filepath.Join(directory, "link") if err := os.Symlink(outside, link); err != nil { t.Fatal(err) } t.Run("lstat reports a symlink without following it", func(t *testing.T) { info, err := files.Lstat(link) if err != nil || !info.IsSymlink || info.IsRegular { t.Errorf("info = %+v, err = %v", info, err) } }) t.Run("it never reads, copies, writes or chmods through a symlink", func(t *testing.T) { if _, err := files.ReadFile(link); err == nil { t.Error("read followed the link") } if err := files.Copy(link, filepath.Join(directory, "copy"), 0o600); err == nil { t.Error("copy followed the link") } if err := files.CreateExclusive(link, []byte("x"), 0o600); err == nil { t.Error("create followed the link") } if err := files.Chmod(link, 0o777); err == nil { t.Error("chmod followed the link") } if content, _ := os.ReadFile(outside); string(content) != "sentinel" { t.Errorf("the target changed: %q", content) } if info, _ := os.Stat(outside); info.Mode().Perm() != 0o644 { t.Errorf("the target mode changed: %v", info.Mode()) } }) t.Run("create-exclusive refuses an existing file and sets the mode", func(t *testing.T) { path := filepath.Join(directory, "exclusive") if err := files.CreateExclusive(path, []byte("one"), 0o640); err != nil { t.Fatal(err) } if err := files.CreateExclusive(path, []byte("two"), 0o640); err == nil { t.Error("the second create must fail") } if info, _ := os.Stat(path); info.Mode().Perm() != 0o640 { t.Errorf("mode = %v", info.Mode()) } }) t.Run("copy, rename, chmod and remove work on regular files", func(t *testing.T) { source := filepath.Join(directory, "source") _ = os.WriteFile(source, []byte("payload"), 0o600) copied := filepath.Join(directory, "copied") if err := files.Copy(source, copied, 0o755); err != nil { t.Fatal(err) } renamed := filepath.Join(directory, "renamed") if err := files.Rename(copied, renamed); err != nil { t.Fatal(err) } if err := files.Chmod(renamed, 0o700); err != nil { t.Fatal(err) } content, _ := files.ReadFile(renamed) info, _ := os.Stat(renamed) if string(content) != "payload" || info.Mode().Perm() != 0o700 { t.Errorf("content = %q, mode = %v", content, info.Mode()) } if err := files.Remove(renamed); err != nil { t.Error(err) } }) t.Run("remove-all unlinks links and never descends into them", func(t *testing.T) { tree := filepath.Join(directory, "tree") _ = os.MkdirAll(filepath.Join(tree, "nested"), 0o755) _ = os.WriteFile(filepath.Join(tree, "nested", "file"), []byte("x"), 0o644) escape := t.TempDir() _ = os.WriteFile(filepath.Join(escape, "keep"), []byte("keep"), 0o644) _ = os.Symlink(escape, filepath.Join(tree, "escape")) if err := files.RemoveAll(tree); err != nil { t.Fatal(err) } if _, err := os.Stat(tree); err == nil { t.Error("the tree must be gone") } if content, _ := os.ReadFile(filepath.Join(escape, "keep")); string(content) != "keep" { t.Error("the link target must be intact") } if err := files.RemoveAll(tree); err != nil { t.Errorf("removing a missing path = %v", err) } }) t.Run("the temp directory is private", func(t *testing.T) { temp, err := files.MakePrivateTempDir() if err != nil { t.Fatal(err) } defer os.RemoveAll(temp) info, _ := os.Stat(temp) if !info.IsDir() || info.Mode().Perm() != 0o700 { t.Errorf("mode = %v", info.Mode()) } }) }