It would be nice to support arbitrarily long lines, but a first step
would be to skip them gracefuly.

The code modifies the loop condition: no tests against ferror(3)/feof(3)
are performed any more (I don't see their point).

We could print a warning on ferror(), though, but that would be another
diff.

ok?


Index: history.c
===================================================================
RCS file: /d/cvs/src/bin/ksh/history.c,v
retrieving revision 1.72
diff -u -p -p -u -r1.72 history.c
--- history.c   18 Oct 2017 15:41:25 -0000      1.72
+++ history.c   18 Oct 2017 20:18:24 -0000
@@ -739,24 +739,45 @@ history_close(void)
 static void
 history_load(Source *s)
 {
-       char            *p, encoded[LINE + 1], line[LINE + 1];
+       char            *nl, *p, encoded[LINE + 1], line[LINE + 1];
 
        rewind(histfh);
+       line_co = 1;
 
        /* just read it all; will auto resize history upon next command */
-       for (line_co = 1; ; line_co++) {
-               p = fgets(encoded, sizeof(encoded), histfh);
-               if (p == NULL || feof(histfh) || ferror(histfh))
-                       break;
-               if ((p = strchr(encoded, '\n')) == NULL) {
-                       bi_errorf("history file is corrupt");
-                       return;
+       for (p = fgets(encoded, sizeof(encoded), histfh); p != NULL;
+            p = fgets(encoded, sizeof(encoded), histfh)) {
+               if ((nl = strchr(encoded, '\n')) == NULL) {
+                       static int corrupt, toolong;
+
+                       /* no trailing newline? */
+                       if (strlen(p) != sizeof(encoded) - 1) {
+                               if (!corrupt) {
+                                       corrupt = 1;
+                                       bi_errorf("history file is corrupt");
+                               }
+                               return;
+                       }
+
+                       if (!toolong) {
+                               toolong = 1;
+                               bi_errorf(
+                                   "ignoring history line(s) longer than %d"
+                                   " bytes", LINE);
+                       }
+
+                       do {
+                               p = fgets(encoded, sizeof(encoded), histfh);
+                       } while (p != NULL && strchr(p, '\n') == NULL);
+
+                       continue;
                }
-               *p = '\0';
+               *nl = '\0';
                s->line = line_co;
                s->cmd_offset = line_co;
                strunvis(line, encoded);
                histsave(line_co, line, 0);
+               line_co++;
        }
 
        history_write();

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to