Skip to content

Commit d3521e6

Browse files
authored
fix(builtins): unescape \/ in sed replacement strings (#1028)
## Summary - Fix `sed` builtin to properly unescape `\/` in replacement strings, producing literal `/` - Also handles `\\` → `\`, `\n` → newline, `\t` → tab in correct order using placeholder approach - Adds spec tests for slash unescaping, back-reference groups with slashes, and escaped backslash ## Test plan - [x] `sed_unescape_slash_in_replacement` — `\/` produces `/` - [x] `sed_regex_groups_with_slash` — back-references with `\/` in date reformatting - [x] `sed_escaped_backslash_in_replacement` — `\\` produces `\` - [x] All existing sed spec tests still pass - [x] Smoke tested via CLI: `echo "abc" | sed 's/b/\//'` → `a/c` Closes #959
1 parent 4e2922e commit d3521e6

3 files changed

Lines changed: 29 additions & 3 deletions

File tree

crates/bashkit/src/builtins/sed.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,13 @@ fn parse_sed_command(s: &str, extended_regex: bool) -> Result<(Option<Address>,
515515
.replace_all(&replacement, r"$${$1}")
516516
.to_string();
517517

518-
// Convert \n → newline, \t → tab in replacement
519-
let replacement = replacement.replace("\\n", "\n").replace("\\t", "\t");
518+
// Convert \n → newline, \t → tab, \/ → /, \\ → \ in replacement
519+
let replacement = replacement
520+
.replace("\\\\", "\x01") // Temporarily escape literal \\
521+
.replace("\\n", "\n")
522+
.replace("\\t", "\t")
523+
.replace("\\/", "/")
524+
.replace("\x01", "\\"); // Restore literal backslash
520525

521526
// Parse nth occurrence from flags (e.g., "2" in s/a/b/2)
522527
let nth = flags

crates/bashkit/tests/spec_cases/sed/sed.test.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,3 +552,24 @@ BAR
552552
BAR
553553
baz
554554
### end
555+
556+
### sed_unescape_slash_in_replacement
557+
# \/ in replacement should produce literal /
558+
echo "abc" | sed 's/b/\//'
559+
### expect
560+
a/c
561+
### end
562+
563+
### sed_regex_groups_with_slash
564+
# back-references with \/ in replacement
565+
echo "2026-01-15" | sed 's/\([0-9]*\)-\([0-9]*\)-\([0-9]*\)/\3\/\2\/\1/'
566+
### expect
567+
15/01/2026
568+
### end
569+
570+
### sed_escaped_backslash_in_replacement
571+
# \\ in replacement should produce literal backslash
572+
echo "abc" | sed 's/b/\\/'
573+
### expect
574+
a\c
575+
### end

supply-chain/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ version = "1.2.1"
579579
criteria = "safe-to-deploy"
580580

581581
[[exemptions.indexmap]]
582-
version = "2.13.0"
582+
version = "2.13.1"
583583
criteria = "safe-to-deploy"
584584

585585
[[exemptions.insta]]

0 commit comments

Comments
 (0)