diff options
| author | historia <[not public]> | 2026-09-18 15:42:23 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-18 15:42:23 -0400 |
| commit | 67e01aab85607b9e601185c7d62dff576af3bb43 (patch) | |
| tree | 059134b2434eba7c14aa9d89f48c5a475feb0312 /internal/player | |
| parent | 7eab582d8a8ee2af1a6baae7baf0696c7005de2e (diff) | |
| download | thehouseoficarus-67e01aab85607b9e601185c7d62dff576af3bb43.tar.gz | |
fix: close map OOM, admin traversal, transport safespot, room rekey, and legacy payout recovery
Diffstat (limited to 'internal/player')
| -rw-r--r-- | internal/player/store.go | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/internal/player/store.go b/internal/player/store.go index 4c8dce5..0b0e70e 100644 --- a/internal/player/store.go +++ b/internal/player/store.go @@ -66,7 +66,18 @@ func (s *AccountStore) AccountExists(name string) bool { return err == nil } +// isPathLikeName reports whether name is unsafe to join into a data-file path. +// Callers are expected to validate names (player.ValidName) before calling the +// store; this is a defence-in-depth backstop for the raw path primitive. +func isPathLikeName(name string) bool { + return name == "" || name == "." || name == ".." || + strings.ContainsAny(name, "/\\") || strings.ContainsRune(name, 0) +} + func (s *AccountStore) FindAccount(name string) (string, error) { + if isPathLikeName(name) { + return "", fmt.Errorf("account not found: %s", name) + } path := s.AccountPath(name) if _, err := os.Stat(path); err == nil { return name, nil @@ -176,6 +187,9 @@ func (s *AccountStore) CharacterExists(name string) bool { } func (s *AccountStore) FindCharacter(name string) (string, error) { + if isPathLikeName(name) { + return "", fmt.Errorf("character not found: %s", name) + } path := s.CharPath(name) if _, err := os.Stat(path); err == nil { return name, nil |
