From 02711b315ba8aa84eaf64d23a356199c47453e37 Mon Sep 17 00:00:00 2001 From: Lawyered Date: Tue, 17 Feb 2026 08:08:57 -0500 Subject: [PATCH] fix(git-ops): avoid panic truncating unicode commit messages (#401) * fix(git-ops): avoid panic truncating unicode commit messages * chore: satisfy rustfmt in git_operations test module --------- Co-authored-by: Clawyered --- src/tools/git_operations.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/tools/git_operations.rs b/src/tools/git_operations.rs index 8635216..21440ba 100644 --- a/src/tools/git_operations.rs +++ b/src/tools/git_operations.rs @@ -279,6 +279,14 @@ impl GitOperationsTool { }) } + fn truncate_commit_message(message: &str) -> String { + if message.chars().count() > 2000 { + format!("{}...", message.chars().take(1997).collect::()) + } else { + message.to_string() + } + } + async fn git_commit(&self, args: serde_json::Value) -> anyhow::Result { let message = args .get("message") @@ -298,11 +306,7 @@ impl GitOperationsTool { } // Limit message length - let message = if sanitized.len() > 2000 { - format!("{}...", &sanitized[..1997]) - } else { - sanitized - }; + let message = Self::truncate_commit_message(&sanitized); let output = self.run_git_command(&["commit", "-m", &message]).await; @@ -754,4 +758,12 @@ mod tests { .unwrap_or("") .contains("Unknown operation")); } + + #[test] + fn truncates_multibyte_commit_message_without_panicking() { + let long = "🦀".repeat(2500); + let truncated = GitOperationsTool::truncate_commit_message(&long); + + assert_eq!(truncated.chars().count(), 2000); + } }