rc

[fork] interactive rc shell
Log | Files | Refs | README | LICENSE

commit 920f0ca9c8b7ae370a3ceaacee2c54662cfdb0fd
parent 85590ce3487c3e5a6edb1a1f4f82a67ea62712e1
Author: tjg <tjg>
Date:   Wed, 27 Nov 2002 12:40:57 +0000

  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:
MChangeLog | 5++++-
Mhistory.c | 22++++++++++------------
2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -816,4 +816,7 @@ Changes since rc-1.5b2 2002-11-27 Bug: history dumps core if more colons than substitutions (thanks - Callum Gibson). + Callum Gibson); history fails to avoid itself if it's the only + command; history writes and reads outside allocated memory. + + Configuration: upgrade to autoconf-2.56 and automake-1.7.1. diff --git 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'))