diff --git a/internal/config/config_validation_internal_test.go b/internal/config/config_validation_internal_test.go index c269a38..8399aba 100644 --- a/internal/config/config_validation_internal_test.go +++ b/internal/config/config_validation_internal_test.go @@ -564,6 +564,60 @@ func TestMalformedConfigFileAbortsStartup(t *testing.T) { t.Logf("got expected error: %v", err) } +// TestConfigFileInDirectoryPixaMayNotEnterAbortsStartup checks that a +// config file pixa cannot read because it may not enter its directory +// aborts startup instead of being passed over. +func TestConfigFileInDirectoryPixaMayNotEnterAbortsStartup(t *testing.T) { + if os.Geteuid() == 0 { + t.Skip("root may enter any directory") + } + + home := t.TempDir() + configDir := filepath.Join(home, ".config", "pixa-test-nonexistent-app") + configPath := filepath.Join(configDir, "config.yml") + + err := os.MkdirAll(configDir, 0o700) + if err != nil { + t.Fatalf("failed to create config directory: %v", err) + } + + err = os.WriteFile(configPath, []byte(signingKeyLine), 0o600) + if err != nil { + t.Fatalf("failed to write config: %v", err) + } + + err = os.Chmod(configDir, 0) + if err != nil { + t.Fatalf("failed to remove the config directory's permissions: %v", err) + } + + // Give the directory back its permissions so t.TempDir can remove it. + t.Cleanup(func() { + //nolint:gosec // G302: a directory needs its execute bit to be removed + _ = os.Chmod(configDir, 0o700) + }) + + // The ~/.config candidate is the only one that exists: the appname + // rules out /etc, and the working directory is empty. + t.Setenv("PIXA_CONFIG_PATH", "") + t.Setenv("HOME", home) + t.Chdir(t.TempDir()) + + log := slog.New(slog.DiscardHandler) + + sc, err := loadConfigFile(log, "pixa-test-nonexistent-app") + if err == nil { + t.Fatalf("config file pixa cannot read must abort startup, got config: %v", + sc) + } + + t.Logf("got expected error: %v", err) + + if !strings.Contains(err.Error(), configPath) { + t.Errorf("error %q does not name the config file %s", err.Error(), configPath) + } +} + func TestEnsureStateDirCreatesDirectory(t *testing.T) { t.Parallel()