diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-16 23:36:58 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-03-16 23:36:58 +0000 |
commit | 4b0bb9e0fd9ec06e9e61b1a1527ace99ea9fe571 (patch) | |
tree | 407d68a79c7ba2a260afea0daaedbae5a12ed84e | |
parent | 486e7ca6b7531d76c9d0e758e1dafe083837a13f (diff) | |
download | busybox-w32-4b0bb9e0fd9ec06e9e61b1a1527ace99ea9fe571.tar.gz busybox-w32-4b0bb9e0fd9ec06e9e61b1a1527ace99ea9fe571.tar.bz2 busybox-w32-4b0bb9e0fd9ec06e9e61b1a1527ace99ea9fe571.zip |
sed: fix very obscure case of escaped newline in sed command
(needed for uclibc build, btw). Add testcase for it.
-rw-r--r-- | editors/sed.c | 41 | ||||
-rwxr-xr-x | testsuite/sed.tests | 4 |
2 files changed, 33 insertions, 12 deletions
diff --git a/editors/sed.c b/editors/sed.c index c434eee1b..f7f22f750 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -1175,21 +1175,38 @@ restart: | |||
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | /* It is possible to have a command line argument with embedded | 1177 | /* It is possible to have a command line argument with embedded |
1178 | newlines. This counts as multiple command lines. */ | 1178 | * newlines. This counts as multiple command lines. |
1179 | * However, newline can be escaped: 's/e/z\<newline>z/' | ||
1180 | * We check for this. | ||
1181 | */ | ||
1179 | 1182 | ||
1180 | static void add_cmd_block(char *cmdstr) | 1183 | static void add_cmd_block(char *cmdstr) |
1181 | { | 1184 | { |
1182 | int go = 1; | 1185 | char *sv, *eol; |
1183 | char *temp = xstrdup(cmdstr), *temp2 = temp; | 1186 | |
1184 | 1187 | cmdstr = sv = xstrdup(cmdstr); | |
1185 | while (go) { | 1188 | do { |
1186 | int len = strcspn(temp2, "\n"); | 1189 | eol = strchr(cmdstr, '\n'); |
1187 | if (!temp2[len]) go = 0; | 1190 | next: |
1188 | else temp2[len] = 0; | 1191 | if (eol) { |
1189 | add_cmd(temp2); | 1192 | /* Count preceding slashes */ |
1190 | temp2 += len+1; | 1193 | int slashes = 0; |
1191 | } | 1194 | char *sl = eol; |
1192 | free(temp); | 1195 | |
1196 | while (sl != cmdstr && *--sl == '\\') | ||
1197 | slashes++; | ||
1198 | /* Odd number of preceding slashes - newline is escaped */ | ||
1199 | if (slashes & 1) { | ||
1200 | strcpy(eol-1, eol); | ||
1201 | eol = strchr(eol, '\n'); | ||
1202 | goto next; | ||
1203 | } | ||
1204 | *eol = '\0'; | ||
1205 | } | ||
1206 | add_cmd(cmdstr); | ||
1207 | cmdstr = eol + 1; | ||
1208 | } while (eol); | ||
1209 | free(sv); | ||
1193 | } | 1210 | } |
1194 | 1211 | ||
1195 | static void add_cmds_link(llist_t *opt_e) | 1212 | static void add_cmds_link(llist_t *opt_e) |
diff --git a/testsuite/sed.tests b/testsuite/sed.tests index 9576b6c4b..a054de6d7 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests | |||
@@ -146,6 +146,10 @@ rm outputw | |||
146 | testing "sed trailing NUL" \ | 146 | testing "sed trailing NUL" \ |
147 | "sed 's/i/z/' input -" \ | 147 | "sed 's/i/z/' input -" \ |
148 | "a\0b\0\nc" "a\0b\0" "c" | 148 | "a\0b\0\nc" "a\0b\0" "c" |
149 | testing "sed escaped newline in command" \ | ||
150 | "sed 's/a/z\\ | ||
151 | z/' input" \ | ||
152 | "z\nz" "a" "" | ||
149 | 153 | ||
150 | # Test end-of-file matching behavior | 154 | # Test end-of-file matching behavior |
151 | 155 | ||