From a54e427cd93d0471ac28bf1d7ce2446ebae294b3 Mon Sep 17 00:00:00 2001 From: Tristan Michael Date: Mon, 30 Mar 2026 16:14:29 -0700 Subject: [PATCH] fix(core): sanitize task filenames to prevent path traversal Replace illegal filesystem characters (/ \ : * ? " < > |) and control characters with underscores. Fall back to task ID as filename if the sanitized title is empty. --- crates/bevy-tasks-core/src/storage.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/bevy-tasks-core/src/storage.rs b/crates/bevy-tasks-core/src/storage.rs index 74b4dae..e6c6a4b 100644 --- a/crates/bevy-tasks-core/src/storage.rs +++ b/crates/bevy-tasks-core/src/storage.rs @@ -148,8 +148,26 @@ impl FileSystemStorage { self.root_path.join(name) } + fn sanitize_filename(name: &str) -> String { + name.chars() + .map(|c| match c { + '/' | '\\' | ':' | '*' | '?' | '"' | '<' | '>' | '|' => '_', + '\0'..='\x1f' => '_', + _ => c, + }) + .collect::() + .trim_matches(|c: char| c == '.' || c == ' ') + .to_string() + } + fn task_file_path(&self, list_dir: &Path, task: &Task) -> PathBuf { - list_dir.join(format!("{}.md", task.title)) + let safe_title = Self::sanitize_filename(&task.title); + let filename = if safe_title.is_empty() { + task.id.to_string() + } else { + safe_title + }; + list_dir.join(format!("{}.md", filename)) } fn parse_markdown_with_frontmatter(&self, content: &str) -> Result<(TaskFrontmatter, String)> {