fix(session): sanitize '/' and '\' in session keys so forum topic keys don't create invalid paths

This commit is contained in:
statxc
2026-03-10 16:11:34 +00:00
parent 54f0680add
commit 2e3e6788ab
3 changed files with 30 additions and 17 deletions
+11 -9
View File
@@ -146,12 +146,15 @@ func (sm *SessionManager) TruncateHistory(key string, keepLast int) {
}
// sanitizeFilename converts a session key into a cross-platform safe filename.
// Session keys use "channel:chatID" (e.g. "telegram:123456") but ':' is the
// volume separator on Windows, so filepath.Base would misinterpret the key.
// We replace it with '_'. The original key is preserved inside the JSON file,
// so loadSessions still maps back to the right in-memory key.
// Replaces ':' with '_' (session key separator) and '/' and '\' with '_' so
// composite IDs (e.g. Telegram forum "chatID/threadID") do not create
// subdirectories or break on Windows. The original key is preserved inside
// the JSON file, so loadSessions still maps back to the right in-memory key.
func sanitizeFilename(key string) string {
return strings.ReplaceAll(key, ":", "_")
s := strings.ReplaceAll(key, ":", "_")
s = strings.ReplaceAll(s, "/", "_")
s = strings.ReplaceAll(s, "\\", "_")
return s
}
func (sm *SessionManager) Save(key string) error {
@@ -162,10 +165,9 @@ func (sm *SessionManager) Save(key string) error {
filename := sanitizeFilename(key)
// filepath.IsLocal rejects empty names, "..", absolute paths, and
// OS-reserved device names (NUL, COM1 … on Windows).
// The extra checks reject "." and any directory separators so that
// the session file is always written directly inside sm.storage.
if filename == "." || !filepath.IsLocal(filename) || strings.ContainsAny(filename, `/\`) {
// OS-reserved device names (NUL, COM1 … on Windows). sanitizeFilename
// already replaced '/' and '\' with '_', so no subdirs are created.
if filename == "." || !filepath.IsLocal(filename) {
return os.ErrInvalid
}