From 9cddc4447e11ab8eb2660b811416225f25cfa03a Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Sun, 4 Oct 2026 11:01:24 +0000 Subject: [PATCH] Test that a config file pixa may not read aborts startup Of the places pixa looks for its config file on its own, a file in a directory pixa may not enter is passed over today and pixa starts without it. This test puts the config file in such a directory and expects startup to abort with an error naming the file. It is skipped when run as root, which may enter any directory. Model: opus-5-5 --- .../config/config_validation_internal_test.go | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) 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()