summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Src/hist.c18
2 files changed, 21 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 0d9395ced..745ce27dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-02-25 Peter Stephenson <pws@csr.com>
+
+ * Src/hist.c: 26602: history substitution buffer could overflow
+ with no test.
+
2009-02-25 Clint Adams <clint@zsh.org>
* Mikael Magnusson: 26596: Completion/Unix/Command/_git: new git
@@ -11232,5 +11237,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4578 $
+* $Revision: 1.4579 $
*****************************************************
diff --git a/Src/hist.c b/Src/hist.c
index 838c06993..dbe1d98a4 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -394,9 +394,10 @@ histsubchar(int c)
zlong ev;
static int marg = -1;
static zlong mev = -1;
- char buf[256], *ptr;
+ char *buf, *ptr;
char *sline;
Histent ehist;
+ size_t buflen;
/* look, no goto's */
if (isfirstch && c == hatchar) {
@@ -445,7 +446,7 @@ histsubchar(int c)
return bangchar;
}
cflag = 0;
- ptr = buf;
+ ptr = buf = zhalloc(buflen = 265);
/* get event number */
@@ -455,8 +456,14 @@ histsubchar(int c)
c = ingetc();
if (c == '?' || c == '\n' || lexstop)
break;
- else
+ else {
*ptr++ = c;
+ if (ptr == buf + buflen) {
+ buf = hrealloc(buf, buflen, 2 * buflen);
+ ptr = buf + buflen;
+ buflen *= 2;
+ }
+ }
}
if (c != '\n' && !lexstop)
c = ingetc();
@@ -484,6 +491,11 @@ histsubchar(int c)
break;
}
*ptr++ = c;
+ if (ptr == buf + buflen) {
+ buf = hrealloc(buf, buflen, 2 * buflen);
+ ptr = buf + buflen;
+ buflen *= 2;
+ }
if (c == '#' || c == bangchar) {
c = ingetc();
break;