瀏覽代碼

sed: fix handling of escaped delimiters in s/// replacement

function                                             old     new   delta
parse_regex_delim                                    111     140     +29

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Denys Vlasenko 2 年之前
父節點
當前提交
f12fb1e409
共有 2 個文件被更改,包括 11 次插入3 次删除
  1. 4 1
      editors/sed.c
  2. 7 2
      testsuite/sed.tests

+ 4 - 1
editors/sed.c

@@ -355,7 +355,10 @@ static int parse_regex_delim(const char *cmdstr, char **match, char **replace)
 	/* save the replacement string */
 	cmdstr_ptr += idx + 1;
 	idx = index_of_next_unescaped_regexp_delim(- (int)delimiter, cmdstr_ptr);
-	*replace = copy_parsing_escapes(cmdstr_ptr, idx, 0);
+//GNU sed 4.8:
+// echo 789 | sed 's&8&\&&'       - 7&9  ("\&" remained "\&")
+// echo 789 | sed 's1\(8\)1\1\11' - 7119 ("\1\1" become "11")
+	*replace = copy_parsing_escapes(cmdstr_ptr, idx, delimiter != '&' ? delimiter : 0);
 
 	return ((cmdstr_ptr - cmdstr) + idx);
 }

+ 7 - 2
testsuite/sed.tests

@@ -329,10 +329,15 @@ testing "sed special char as s/// delimiter, in pattern" \
 	"sed 's+9\++X+'" \
 	"X8=17\n" "" "9+8=17\n"
 
-# but in replacement string, "\&" remains "\&", not interpreted as "&"
-testing "sed special char as s/// delimiter, in replacement" \
+# Matching GNU sed 4.8:
+# in replacement string, "\&" remains "\&", not interpreted as "&"
+testing "sed special char as s/// delimiter, in replacement 1" \
 	"sed 's&9&X\&&'" \
 	"X&+8=17\n" "" "9+8=17\n"
+# in replacement string, "\1" is interpreted as "1"
+testing "sed special char as s/// delimiter, in replacement 2" \
+	"sed 's1\(9\)1X\11'" \
+	"X1+8=17\n" "" "9+8=17\n"
 
 testing "sed /\$_in_regex/ should not match newlines, only end-of-line" \
 	"sed ': testcont; /\\\\$/{ =; N; b testcont }'" \