diff options
author | fenner <fenner@FreeBSD.org> | 2003-05-31 06:27:57 +0000 |
---|---|---|
committer | fenner <fenner@FreeBSD.org> | 2003-05-31 06:27:57 +0000 |
commit | 99d6402b40e6d534ef3962adcca557fe577f1021 (patch) | |
tree | e2c710b6451b3183b118d6437dd5c1e4a9a94e64 /bin/sh | |
parent | 340f6115ced94734378a46300e6fdc887146fa2e (diff) | |
download | FreeBSD-src-99d6402b40e6d534ef3962adcca557fe577f1021.zip FreeBSD-src-99d6402b40e6d534ef3962adcca557fe577f1021.tar.gz |
Instead of eating trailing newlines after inserting them into the
output buffer, don't insert them at all. This prevents a buffer
*underrun* when the substitution consists completely of newlines
(e.g. `echo`) and the byte before the source buffer to which p
points is a '\n', in which case more characters would be removed
from the output buffer than were inserted.
This fixes certain port builds on sparc64.
Approved by: re (scottl)
Reviewed by: des, tjr
Diffstat (limited to 'bin/sh')
-rw-r--r-- | bin/sh/expand.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/bin/sh/expand.c b/bin/sh/expand.c index e3748ab..214f53a 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -437,6 +437,7 @@ expbackq(union node *cmd, int quoted, int flag) char const *syntax = quoted? DQSYNTAX : BASESYNTAX; int saveherefd; int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); + int nnl; INTOFF; saveifs = ifsfirst; @@ -454,6 +455,8 @@ expbackq(union node *cmd, int quoted, int flag) p = in.buf; lastc = '\0'; + nnl = 0; + /* Don't copy trailing newlines */ for (;;) { if (--in.nleft < 0) { if (in.fd < 0) @@ -469,14 +472,18 @@ expbackq(union node *cmd, int quoted, int flag) if (lastc != '\0') { if (quotes && syntax[(int)lastc] == CCTL) STPUTC(CTLESC, dest); - STPUTC(lastc, dest); + if (lastc == '\n') { + nnl++; + } else { + while (nnl > 0) { + nnl--; + STPUTC('\n', dest); + } + STPUTC(lastc, dest); + } } } - /* Eat all trailing newlines */ - for (p--; lastc == '\n'; lastc = *--p) - STUNPUTC(dest); - if (in.fd >= 0) close(in.fd); if (in.buf) |