Commit e153bd83abef6516a818eebb7b323f421e654782

Nick Gasson 2014-01-06T11:04:02

Fix escape sequence processing when only one byte available The read call in the escape sequence processing does not handle the case where only the first byte is available. This can happen for example on a slow serial terminal. Comment by @antirez: I reworked the code for brevity, for historical reasons here is the proposed patch. I believe my fix should be functionally equivalent. Original fix: case 27: /* escape sequence */ /* Read the next two bytes representing the escape sequence. */ - if (read(fd,seq,2) == -1) break; + { + ssize_t b = read(fd, seq, 2); + + if (b < 0) break; + + if (b == 1) { + b = read(fd,&seq[1], 1); + if (b != 1) { + break; + } + } + } See PR #47.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
diff --git a/linenoise.c b/linenoise.c
index 172bb39..35aaf5e 100644
--- a/linenoise.c
+++ b/linenoise.c
@@ -734,8 +734,11 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen, 
             linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT);
             break;
         case ESC:    /* escape sequence */
-            /* Read the next two bytes representing the escape sequence. */
-            if (read(l.ifd,seq,2) == -1) break;
+            /* Read the next two bytes representing the escape sequence.
+             * Use two calls to handle slow terminals returning the two
+             * chars at different times. */
+            if (read(l.ifd,seq,1) == -1) break;
+            if (read(l.ifd,seq+1,1) == -1) break;
 
             if (seq[0] == 91 && seq[1] == 68) {
                 /* Left arrow */