summaryrefslogtreecommitdiffstats
path: root/bin/sh
diff options
context:
space:
mode:
authorfenner <fenner@FreeBSD.org>2003-05-31 06:27:57 +0000
committerfenner <fenner@FreeBSD.org>2003-05-31 06:27:57 +0000
commit99d6402b40e6d534ef3962adcca557fe577f1021 (patch)
treee2c710b6451b3183b118d6437dd5c1e4a9a94e64 /bin/sh
parent340f6115ced94734378a46300e6fdc887146fa2e (diff)
downloadFreeBSD-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.c17
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)
OpenPOWER on IntegriCloud