diff options
author | Denis Vlasenko | 2007-03-16 23:36:58 +0000 |
---|---|---|
committer | Denis Vlasenko | 2007-03-16 23:36:58 +0000 |
commit | 4b0bb9e0fd9ec06e9e61b1a1527ace99ea9fe571 (patch) | |
tree | 407d68a79c7ba2a260afea0daaedbae5a12ed84e /editors/sed.c | |
parent | 486e7ca6b7531d76c9d0e758e1dafe083837a13f (diff) | |
download | busybox-4b0bb9e0fd9ec06e9e61b1a1527ace99ea9fe571.zip busybox-4b0bb9e0fd9ec06e9e61b1a1527ace99ea9fe571.tar.gz |
sed: fix very obscure case of escaped newline in sed command
(needed for uclibc build, btw). Add testcase for it.
Diffstat (limited to 'editors/sed.c')
-rw-r--r-- | editors/sed.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/editors/sed.c b/editors/sed.c index c434eee..f7f22f7 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -1175,21 +1175,38 @@ restart: } /* It is possible to have a command line argument with embedded - newlines. This counts as multiple command lines. */ + * newlines. This counts as multiple command lines. + * However, newline can be escaped: 's/e/z\<newline>z/' + * We check for this. + */ static void add_cmd_block(char *cmdstr) { - int go = 1; - char *temp = xstrdup(cmdstr), *temp2 = temp; - - while (go) { - int len = strcspn(temp2, "\n"); - if (!temp2[len]) go = 0; - else temp2[len] = 0; - add_cmd(temp2); - temp2 += len+1; - } - free(temp); + char *sv, *eol; + + cmdstr = sv = xstrdup(cmdstr); + do { + eol = strchr(cmdstr, '\n'); + next: + if (eol) { + /* Count preceding slashes */ + int slashes = 0; + char *sl = eol; + + while (sl != cmdstr && *--sl == '\\') + slashes++; + /* Odd number of preceding slashes - newline is escaped */ + if (slashes & 1) { + strcpy(eol-1, eol); + eol = strchr(eol, '\n'); + goto next; + } + *eol = '\0'; + } + add_cmd(cmdstr); + cmdstr = eol + 1; + } while (eol); + free(sv); } static void add_cmds_link(llist_t *opt_e) |