summaryrefslogtreecommitdiff
path: root/history.c
diff options
context:
space:
mode:
authortjg <tjg>2002-11-27 12:40:57 +0000
committerToby Goodwin <toby@paccrat.org>2015-05-16 21:23:23 +0100
commit920f0ca9c8b7ae370a3ceaacee2c54662cfdb0fd (patch)
treef8223bf9ca325260429e956b5a078c9b882f3b55 /history.c
parent85590ce3487c3e5a6edb1a1f4f82a67ea62712e1 (diff)
Bug: history dumps core if more colons than substitutions (thanks
Callum Gibson); history fails to avoid itself if it's the only command; history writes and reads outside allocated memory.
Diffstat (limited to 'history.c')
-rw-r--r--history.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/history.c b/history.c
index 8be90ec..1f22f2e 100644
--- a/history.c
+++ b/history.c
@@ -208,9 +208,9 @@ static char *readhistoryfile(char **last) {
exit(1);
}
- size = 0;
- count = 0;
- buf = ealloc(size = CHUNKSIZE);
+ size = CHUNKSIZE;
+ buf = ealloc(size);
+ buf[0] = '\0'; count = 1; /* sentinel */
while ((nread = fread(buf + count, sizeof (char), size - count, histfile)) > 0) {
count += nread;
if (size - count == 0)
@@ -224,32 +224,30 @@ static char *readhistoryfile(char **last) {
return buf;
}
-static char *getcommand() {
+static char *getcommand(void) {
char *s, *t;
static char *hist = NULL, *last;
if (hist == NULL) {
hist = readhistoryfile(&last);
- *--last = '\0'; /* trim final newline */
+ *--last = '\0'; /* replaces final newline */
+ ++hist; /* start beyond sentinel */
}
again: s = last;
if (s < hist)
return NULL;
- while (*--s != '\n')
- if (s <= hist) {
- last = hist - 1;
- return hist;
- }
+ while (s >= hist && *s != '\n')
+ --s;
*s = '\0';
last = s++;
/*
* if the command contains the "me" character at the start of the line
- * or after any of [`{|()@] then try again
+ * or after any of [`{|()@/] then try again
*/
- for (t = s; *t != '\0'; t++)
+ for (t = s; *t != '\0'; ++t)
if (*t == me) {
char *u = t - 1;
while (u >= s && (*u == ' ' || *u == '\t'))