diff options
author | obrien <obrien@FreeBSD.org> | 2010-10-13 23:29:09 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2010-10-13 23:29:09 +0000 |
commit | 04029327665ca3c97ae07cae698d5df760f2b68e (patch) | |
tree | 21a2e1390b3cbd0e8029830cf4195a75dba0d1e7 /bin/sh/memalloc.c | |
parent | 256615c9b37c8059eef0e130fbf813607a5396a8 (diff) | |
download | FreeBSD-src-04029327665ca3c97ae07cae698d5df760f2b68e.zip FreeBSD-src-04029327665ca3c97ae07cae698d5df760f2b68e.tar.gz |
Do not assume in growstackstr() that a "precious" character will be
immediately written into the stack after the call. Instead let the caller
manage the "space left".
Previously, growstackstr()'s assumption causes problems with STACKSTRNUL()
where we want to be able to turn a stack into a C string, and later
pretend the NUL is not there.
This fixes a bug in STACKSTRNUL() (that grew the stack) where:
1. STADJUST() called after a STACKSTRNUL() results in an improper adjust.
This can be seen in ${var%pattern} and ${var%%pattern} evaluation.
2. Memory leak in STPUTC() called after a STACKSTRNUL().
Reviewed by: jilles
Diffstat (limited to 'bin/sh/memalloc.c')
-rw-r--r-- | bin/sh/memalloc.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/bin/sh/memalloc.c b/bin/sh/memalloc.c index 01bddb2..9158719 100644 --- a/bin/sh/memalloc.c +++ b/bin/sh/memalloc.c @@ -295,6 +295,13 @@ grabstackblock(int len) * is space for at least one character. */ +static char * +growstrstackblock(int n) +{ + growstackblock(); + sstrnleft = stackblocksize() - n; + return stackblock() + n; +} char * growstackstr(void) @@ -304,12 +311,10 @@ growstackstr(void) len = stackblocksize(); if (herefd >= 0 && len >= 1024) { xwrite(herefd, stackblock(), len); - sstrnleft = len - 1; + sstrnleft = len; return stackblock(); } - growstackblock(); - sstrnleft = stackblocksize() - len - 1; - return stackblock() + len; + return growstrstackblock(len); } @@ -323,9 +328,7 @@ makestrspace(void) int len; len = stackblocksize() - sstrnleft; - growstackblock(); - sstrnleft = stackblocksize() - len; - return stackblock() + len; + return growstrstackblock(len); } |