From 8cfc647b2c41576cae07f30d57c3903e7324fb69 Mon Sep 17 00:00:00 2001 From: Martin Natano Date: Thu, 30 Jul 2015 08:37:42 +0200 Subject: [PATCH] Account for newlines in substitution (s///) commands. Substitution commands might contain a newline in the replacement pattern (escaped with a backslash before it), causing patch's understanding of the state the ed child process is in to diverge from reality. This can lead to patch unwillingly feeding '!' (execute shell command) lines to ed. Finding out how to do this is left as an exercise to the reader. ok pedro@ --- usr.bin/patch/pch.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c index ea0ba7130bc..35a7c62adfe 100644 --- a/usr.bin/patch/pch.c +++ b/usr.bin/patch/pch.c @@ -1369,6 +1369,7 @@ do_ed_script(void) char *t; long beginning_of_this_line; FILE *pipefp = NULL; + int continuation; if (!skip_rest_of_patch) { if (copy_file(filearg[0], TMPOUTNAME) < 0) { @@ -1393,7 +1394,19 @@ do_ed_script(void) (*t == 'a' || *t == 'c' || *t == 'd' || *t == 'i' || *t == 's')) { if (pipefp != NULL) fputs(buf, pipefp); - if (*t != 'd') { + if (*t == 's') { + for (;;) { + continuation = 0; + t = strchr(buf, '\0') - 1; + while (--t >= buf && *t == '\\') + continuation = !continuation; + if (!continuation || + pgets(buf, sizeof buf, pfp) == NULL) + break; + if (pipefp != NULL) + fputs(buf, pipefp); + } + } else if (*t != 'd') { while (pgets(buf, sizeof buf, pfp) != NULL) { p_input_line++; if (pipefp != NULL)