diff options
| author | tjg <tjg> | 2002-11-27 12:40:57 +0000 |
|---|---|---|
| committer | Toby Goodwin <toby@paccrat.org> | 2015-05-16 21:23:23 +0100 |
| commit | 920f0ca9c8b7ae370a3ceaacee2c54662cfdb0fd (patch) | |
| tree | f8223bf9ca325260429e956b5a078c9b882f3b55 /history.c | |
| parent | 85590ce3487c3e5a6edb1a1f4f82a67ea62712e1 (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.c | 22 |
1 files changed, 10 insertions, 12 deletions
@@ -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')) |