about summary refs log tree commit diff
path: root/Src/hist.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2009-02-25 10:30:14 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2009-02-25 10:30:14 +0000
commit3b88638729137b72e3541a07feabe26d5d49ad1c (patch)
tree03f5728d18b8ba57a05b2bd3c1b4ba1a180256f7 /Src/hist.c
parent10182c766bf6096ab2ffc25ba73babe6955dff0a (diff)
downloadzsh-3b88638729137b72e3541a07feabe26d5d49ad1c.tar.gz
zsh-3b88638729137b72e3541a07feabe26d5d49ad1c.tar.xz
zsh-3b88638729137b72e3541a07feabe26d5d49ad1c.zip
26602: history substitution buffer could overflow with no test
Diffstat (limited to 'Src/hist.c')
-rw-r--r--Src/hist.c18
1 files changed, 15 insertions, 3 deletions
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;