sed: fix very obscure case of escaped newline in sed command

(needed for uclibc build, btw). Add testcase for it.
This commit is contained in:
Denis Vlasenko
2007-03-16 23:36:58 +00:00
parent 486e7ca6b7
commit 4b0bb9e0fd
2 changed files with 32 additions and 11 deletions

View File

@@ -1175,21 +1175,38 @@ restart:
} }
/* It is possible to have a command line argument with embedded /* 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) static void add_cmd_block(char *cmdstr)
{ {
int go = 1; char *sv, *eol;
char *temp = xstrdup(cmdstr), *temp2 = temp;
while (go) { cmdstr = sv = xstrdup(cmdstr);
int len = strcspn(temp2, "\n"); do {
if (!temp2[len]) go = 0; eol = strchr(cmdstr, '\n');
else temp2[len] = 0; next:
add_cmd(temp2); if (eol) {
temp2 += len+1; /* Count preceding slashes */
} int slashes = 0;
free(temp); 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) static void add_cmds_link(llist_t *opt_e)

View File

@@ -146,6 +146,10 @@ rm outputw
testing "sed trailing NUL" \ testing "sed trailing NUL" \
"sed 's/i/z/' input -" \ "sed 's/i/z/' input -" \
"a\0b\0\nc" "a\0b\0" "c" "a\0b\0\nc" "a\0b\0" "c"
testing "sed escaped newline in command" \
"sed 's/a/z\\
z/' input" \
"z\nz" "a" ""
# Test end-of-file matching behavior # Test end-of-file matching behavior