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

Reply via email to