summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/histedit.c2
-rw-r--r--bin/sh/memalloc.c17
-rw-r--r--bin/sh/memalloc.h9
-rw-r--r--tools/regression/bin/sh/expansion/trim4.015
4 files changed, 34 insertions, 9 deletions
diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c
index 7773ad8..dab69f1 100644
--- a/bin/sh/histedit.c
+++ b/bin/sh/histedit.c
@@ -418,7 +418,7 @@ fc_replace(const char *s, char *p, char *r)
} else
STPUTC(*s++, dest);
}
- STACKSTRNUL(dest);
+ STPUTC('\0', dest);
dest = grabstackstr(dest);
return (dest);
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);
}
diff --git a/bin/sh/memalloc.h b/bin/sh/memalloc.h
index 187d4c8..563927a 100644
--- a/bin/sh/memalloc.h
+++ b/bin/sh/memalloc.h
@@ -67,9 +67,16 @@ void ungrabstackstr(char *, char *);
#define stackblock() stacknxt
#define stackblocksize() stacknleft
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
-#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
+#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), --sstrnleft, *p++ = (c)))
#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); }
#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
+/*
+ * STACKSTRNUL's use is where we want to be able to turn a stack
+ * (non-sentinel, character counting string) into a C string,
+ * and later pretend the NUL is not there.
+ * Note: Because of STACKSTRNUL's semantics, STACKSTRNUL cannot be used
+ * on a stack that will grabstackstr()ed.
+ */
#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
#define STUNPUTC(p) (++sstrnleft, --p)
#define STTOPC(p) p[-1]
diff --git a/tools/regression/bin/sh/expansion/trim4.0 b/tools/regression/bin/sh/expansion/trim4.0
new file mode 100644
index 0000000..1000bd3
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/trim4.0
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+v1=/homes/SOME_USER
+v2=
+v3=C123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+
+# Trigger bug in VSTRIMRIGHT processing STADJUST() call in expand.c:subevalvar()
+while [ ${#v2} -lt 2000 ]; do
+ v4="${v2} ${v1%/*} $v3"
+ if [ ${#v4} -ne $((${#v2} + ${#v3} + 8)) ]; then
+ echo bad: ${#v4} -ne $((${#v2} + ${#v3} + 8))
+ fi
+ v2=x$v2
+ v3=y$v3
+done
OpenPOWER on IntegriCloud