From 2a3b4221375235fb94aa083fec3ccfed06a96d0c Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Wed, 29 Nov 2017 14:53:14 +0100 Subject: [PATCH] Fix negative array index triggered by i-search This is a fix to a bug reported by Claus Fischer. When doing a reversed i-search on the history, clear_line() sets rl_point to a negative value, which is later used by ceol(). The intention is to clear the whole line for the new Search: prompt, but indexing an array with a negative value is strongly discouraged. To prevent this negative indexing from happening we check in ceol() for rl_point < 0, but we quickly notice another side effect: one lingering character at the end of line when returning from i-search. The problem manifests itself more cleary when having a looooo000ooonong prompt. The fix is to rub out the extra space, insert the i-search string, and *then* call ceol() again. Thanks to Claus for pointing this out! Signed-off-by: Joachim Nilsson --- src/editline.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/editline.c b/src/editline.c index 9b549db..0142a81 100644 --- a/src/editline.c +++ b/src/editline.c @@ -431,11 +431,17 @@ static el_status_t case_cap_word(void) static void ceol(void) { - int extras; + int extras = 0; int i; char *p; - for (extras = 0, i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) { + while (rl_point < 0) { + tty_put(' '); + rl_point++; + extras++; + } + + for (i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) { tty_put(' '); if (ISMETA(*p)) { if (rl_meta_chars) { @@ -443,7 +449,7 @@ static void ceol(void) tty_put(' '); extras += 2; } - } if (ISCTL(*p)) { + } else if (ISCTL(*p)) { tty_put(' '); extras++; } @@ -525,15 +531,19 @@ static const char *prev_hist(void) static el_status_t do_insert_hist(const char *p) { + el_status_t ret; + if (p == NULL) return el_ring_bell(); rl_point = 0; reposition(); - ceol(); rl_end = 0; - return insert_string(p); + ret = insert_string(p); + ceol(); + + return ret; } static el_status_t do_hist(const char *(*move)(void))