aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/mobius/config.go7
-rw-r--r--internal/mobius/config_test.go39
2 files changed, 41 insertions, 5 deletions
diff --git a/internal/mobius/config.go b/internal/mobius/config.go
index 6e5fb9f..171f6c7 100644
--- a/internal/mobius/config.go
+++ b/internal/mobius/config.go
@@ -52,10 +52,7 @@ func LoadConfig(path string) (*hotline.Config, error) {
return nil, fmt.Errorf("validate config: %v", err)
}
- // If the FileRoot is an absolute path, use it, otherwise treat as a relative path to the config dir.
- if !filepath.IsAbs(config.FileRoot) {
- config.FileRoot = filepath.Join(path, "../", config.FileRoot)
- }
-
+ // FileRoot is returned verbatim: it is a path within the selected file store's namespace, so
+ // only the caller knows how to resolve it (e.g. against the config dir for the OS backend).
return &config, nil
}
diff --git a/internal/mobius/config_test.go b/internal/mobius/config_test.go
index b76b16d..bed739d 100644
--- a/internal/mobius/config_test.go
+++ b/internal/mobius/config_test.go
@@ -41,6 +41,45 @@ FileRoot: "files"
}
}
+// TestLoadConfig_FileRootKeptVerbatim guards against LoadConfig resolving FileRoot to a host
+// filesystem path. FileRoot is a path within the selected file store's namespace; rewriting it to
+// a local absolute path here would leak the host's directory layout into object-store keys.
+func TestLoadConfig_FileRootKeptVerbatim(t *testing.T) {
+ tests := []struct {
+ name string
+ fileRoot string
+ }{
+ {"relative path", "files"},
+ {"nested relative path", "library/files"},
+ {"absolute path", "/srv/hotline/files"},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ tmpDir := t.TempDir()
+
+ configContent := `
+Name: "Test Server"
+Description: "Test Description"
+FileRoot: "` + tt.fileRoot + `"
+`
+ configPath := filepath.Join(tmpDir, "config.yaml")
+ if err := os.WriteFile(configPath, []byte(configContent), 0644); err != nil {
+ t.Fatalf("Failed to write config file: %v", err)
+ }
+
+ config, err := LoadConfig(configPath)
+ if err != nil {
+ t.Fatalf("Expected no error, got: %v", err)
+ }
+
+ if config.FileRoot != tt.fileRoot {
+ t.Errorf("Expected FileRoot to be %q, got %q", tt.fileRoot, config.FileRoot)
+ }
+ })
+ }
+}
+
func TestLoadConfig_ValidBannerFileExtensions(t *testing.T) {
tests := []struct {
name string