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 <clawyered@macbookair.home>
This commit is contained in:
Lawyered 2026-02-17 08:08:57 -05:00 committed by GitHub
parent b09e77c8c9
commit 02711b315b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -279,6 +279,14 @@ impl GitOperationsTool {
}) })
} }
fn truncate_commit_message(message: &str) -> String {
if message.chars().count() > 2000 {
format!("{}...", message.chars().take(1997).collect::<String>())
} else {
message.to_string()
}
}
async fn git_commit(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> { async fn git_commit(&self, args: serde_json::Value) -> anyhow::Result<ToolResult> {
let message = args let message = args
.get("message") .get("message")
@ -298,11 +306,7 @@ impl GitOperationsTool {
} }
// Limit message length // Limit message length
let message = if sanitized.len() > 2000 { let message = Self::truncate_commit_message(&sanitized);
format!("{}...", &sanitized[..1997])
} else {
sanitized
};
let output = self.run_git_command(&["commit", "-m", &message]).await; let output = self.run_git_command(&["commit", "-m", &message]).await;
@ -754,4 +758,12 @@ mod tests {
.unwrap_or("") .unwrap_or("")
.contains("Unknown operation")); .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);
}
} }