From 29f10652498edb04ca608c410bbc3b1a775b6066 Mon Sep 17 00:00:00 2001 From: usuallyarnav Date: Sat, 25 Jul 2026 13:31:11 +0530 Subject: [PATCH] Sanitize channel names before using them as filenames --- boundier/storage/sqlite_store.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/boundier/storage/sqlite_store.py b/boundier/storage/sqlite_store.py index 7cdbcad..d7debb2 100644 --- a/boundier/storage/sqlite_store.py +++ b/boundier/storage/sqlite_store.py @@ -1,4 +1,5 @@ import os +import re import sqlite3 import logging from datetime import datetime @@ -18,6 +19,12 @@ def _get_conn(self): conn.row_factory = sqlite3.Row return conn + @staticmethod + def _safe_name(name: str) -> str: + """Sanitize a channel name for safe use as a filename (prevents path traversal).""" + cleaned = re.sub(r"[^a-zA-Z0-9_-]+", "-", name).strip("-") + return cleaned[:64] or "channel" + def _init_db(self): """Initializes database schema if missing and creates memory backup folders.""" logger.info(f"Initializing SQLite database at: {self.db_path}") @@ -84,7 +91,7 @@ def sync_markdown_files(self): for row in cursor.fetchall(): ch_name = row["channel_name"] ch_summary = row["channel_summary"] or "" - file_path = os.path.join(self.memory_dir, f"{ch_name}.md") + file_path = os.path.join(self.memory_dir, f"{self._safe_name(ch_name)}.md") # Check if file needs to be updated write_file = True @@ -121,7 +128,7 @@ def save_channel(self, channel_id: int, channel_name: str, category_id: Optional (channel_id, channel_name, category_id, category_name, summary) ) # Sync directly to local markdown file - file_path = os.path.join(self.memory_dir, f"{channel_name}.md") + file_path = os.path.join(self.memory_dir, f"{self._safe_name(channel_name)}.md") with open(file_path, "w", encoding="utf-8") as f: f.write(summary) finally: