From 2d7cee30b6455eddfb7c9fff81ab308e49a94ab7 Mon Sep 17 00:00:00 2001 From: dalbee Date: Wed, 13 May 2026 09:31:29 +0900 Subject: [PATCH] Preserve double-digit command placeholders Command templates replace numbered placeholders with literal string replacement. Replacing in ascending order lets short placeholders such as $1 consume the prefix of $10 before the intended replacement runs, so templates with double-digit placeholders produce corrupted output. Constraint: Keep existing last-placeholder-captures-rest behavior unchanged Rejected: Regex replacement rewrite | larger change than needed for the prefix-collision bug Confidence: high Scope-risk: narrow Directive: Preserve descending replacement unless the placeholder parser is replaced with token-aware substitution Tested: Docker rust:latest cargo test -p cortex-commands test_substitute_two_digit_placeholders_before_prefixes -- --nocapture Tested: Docker rust:latest cargo test -p cortex-commands substitute -- --nocapture Tested: Docker rust:latest cargo check -p cortex-commands Tested: Docker rust:latest cargo fmt --check --package cortex-commands Tested: git diff --check --- src/cortex-commands/src/command.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/cortex-commands/src/command.rs b/src/cortex-commands/src/command.rs index 8a7b42840..3202101dc 100644 --- a/src/cortex-commands/src/command.rs +++ b/src/cortex-commands/src/command.rs @@ -209,8 +209,8 @@ pub fn substitute_placeholders(template: &str, arguments: &str) -> String { // Find the highest numbered placeholder let max_placeholder = find_max_placeholder(&result); - // Replace numbered placeholders - for i in 1..=max_placeholder { + // Replace longer placeholders first so `$1` does not corrupt `$10`. + for i in (1..=max_placeholder).rev() { let placeholder = format!("${i}"); let replacement = if i == max_placeholder { // Last placeholder captures all remaining arguments @@ -374,6 +374,17 @@ No closing delimiter"#; assert_eq!(result, "A: only_one, B: , C: "); } + #[test] + fn test_substitute_two_digit_placeholders_before_prefixes() { + let template = "Run $1 and item $10"; + let result = substitute_placeholders( + template, + "alpha beta gamma delta epsilon zeta eta theta iota kappa", + ); + + assert_eq!(result, "Run alpha and item kappa"); + } + #[test] fn test_command_parse() { let content = r#"---