The code in sethistsize() is bogus when we want to shrink the array:
- the memmove doesn't copy the last command (which should be
HISTSIZE=...)
- trying to access *histptr immediately would trigger a crash, as it
points one element past the array
To reproduce: type HISTSIZE=3, hit <Up> (emacs mode).
I think both problems find their root in the fact that cursize is
misnamed. The following seems to properly handle all cases here.
Comments / ok?
Index: history.c
===================================================================
RCS file: /d/cvs/src/bin/ksh/history.c,v
retrieving revision 1.64
diff -u -p -p -u -r1.64 history.c
--- history.c 11 Aug 2017 19:37:58 -0000 1.64
+++ history.c 25 Aug 2017 20:53:22 -0000
@@ -509,18 +509,17 @@ void
sethistsize(int n)
{
if (n > 0 && n != histsize) {
- int cursize = histptr - history;
+ int offset = histptr - history;
/* save most recent history */
- if (n < cursize) {
- memmove(history, histptr - n, n * sizeof(char *));
- cursize = n;
+ if (offset > n - 1) {
+ offset = n - 1;
+ memmove(history, histptr - offset, n * sizeof(char *));
}
history = areallocarray(history, n, sizeof(char *), APERM);
-
histsize = n;
- histptr = history + cursize;
+ histptr = history + offset;
}
}
--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE