about summary refs log tree commit diff
path: root/Src/hist.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@users.sourceforge.net>2001-10-30 18:13:02 +0000
committerWayne Davison <wayned@users.sourceforge.net>2001-10-30 18:13:02 +0000
commit51a7b33f90096077cadd345a599280b39cdf55c0 (patch)
treef16674c8d0043f37467e9637617d3d831dc6c082 /Src/hist.c
parentb71ae6bcb06b6d67cd4525412898669ba5e7578b (diff)
downloadzsh-51a7b33f90096077cadd345a599280b39cdf55c0.tar.gz
zsh-51a7b33f90096077cadd345a599280b39cdf55c0.tar.xz
zsh-51a7b33f90096077cadd345a599280b39cdf55c0.zip
Improved readhistline() to reject binary data better. (16184)
Diffstat (limited to 'Src/hist.c')
-rw-r--r--Src/hist.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/Src/hist.c b/Src/hist.c
index 4dacdd337..dfd34c716 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -1766,31 +1766,34 @@ static struct {
 
 static int histfile_linect;
 
-static int readhistline(int start, char **bufp, int *bufsiz, FILE *in)
+static int
+readhistline(int start, char **bufp, int *bufsiz, FILE *in)
 {
     char *buf = *bufp;
     if (fgets(buf + start, *bufsiz - start, in)) {
-	int l = strlen(buf);
-
-	if (start >= l)
+	int len = start + strlen(buf + start);
+	if (len == start)
 	    return -1;
-
-	if (l) {
-	    if (buf[l - 1] != '\n' && !feof(in)) {
+	if (buf[len - 1] != '\n') {
+	    if (!feof(in)) {
+		if (len < (*bufsiz) - 1)
+		    return -1;
 		*bufp = zrealloc(buf, 2 * (*bufsiz));
 		*bufsiz = 2 * (*bufsiz);
-		return readhistline(l, bufp, bufsiz, in);
+		return readhistline(len, bufp, bufsiz, in);
 	    }
-	    buf[l - 1] = '\0';
-	    if (l > 1 && buf[l - 2] == '\\') {
-		buf[--l - 1] = '\n';
+	}
+	else {
+	    buf[len - 1] = '\0';
+	    if (len > 1 && buf[len - 2] == '\\') {
+		buf[--len - 1] = '\n';
 		if (!feof(in))
-		    return readhistline(l, bufp, bufsiz, in);
+		    return readhistline(len, bufp, bufsiz, in);
 	    }
 	}
-	return l;
-    } else
-	return 0;
+	return len;
+    }
+    return 0;
 }
 
 /**/