diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2015-07-31 00:24:15 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2015-07-31 00:24:15 +0000 |
commit | 1c735ccd758b440a4e17bc2b6bf406deb6d3a940 (patch) | |
tree | b7f0f84e1c46843b74a04676b47cb4c3ba2ce1f1 /usr.bin/patch | |
parent | e406ddef5cb3926a5baff42b644aaa3b6e52fe06 (diff) |
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. From Martin Natano. OK deraadt@
Diffstat (limited to 'usr.bin/patch')
-rw-r--r-- | usr.bin/patch/pch.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c index 36cd608bc5e..bd434f40bbc 100644 --- a/usr.bin/patch/pch.c +++ b/usr.bin/patch/pch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pch.c,v 1.52 2015/07/26 14:32:19 millert Exp $ */ +/* $OpenBSD: pch.c,v 1.53 2015/07/31 00:24:14 millert Exp $ */ /* * patch - a program to apply diffs to original files @@ -1402,7 +1402,19 @@ do_ed_script(void) *t != '\0' && strchr("acdis", *t) != NULL) { if (pipefp != NULL) fputs(buf, pipefp); - if (*t != 'd' && *t != 's') { + if (*t == 's') { + for (;;) { + bool continued = false; + t = buf + strlen(buf) - 1; + while (--t >= buf && *t == '\\') + continued = !continued; + if (!continued || + 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) |