From a5ad77accf401578f2707ade427919e379fb4ef0 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Fri, 12 Jan 2024 13:43:35 +0100 Subject: [PATCH] fix(console): Fixed linenoise prompt length calculation This commit fixes a potential issue where in the prompt length used for the linenoise based console could be calculated as a negative integer, leading to a console hang. Closes https://github.com/espressif/esp-idf/issues/4924 --- components/console/linenoise/linenoise.c | 28 +++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/components/console/linenoise/linenoise.c b/components/console/linenoise/linenoise.c index 48e510f521..3a94e81b00 100644 --- a/components/console/linenoise/linenoise.c +++ b/components/console/linenoise/linenoise.c @@ -804,6 +804,23 @@ uint32_t getMillis(void) { return tv.tv_sec * 1000 + tv.tv_usec / 1000; } +static inline size_t prompt_len_ignore_escape_seq(const char *prompt) { + size_t plen = 0; + bool in_escape_sequence = false; + + for (; *prompt != '\0'; ++prompt) { + if (*prompt == '\033') { + in_escape_sequence = true; + } else if (in_escape_sequence && *prompt == 'm') { + in_escape_sequence = false; + } else if (!in_escape_sequence) { + ++plen; + } + } + + return plen; +} + /* This function is the core of the line editing capability of linenoise. * It expects 'fd' to be already in "raw mode" so that every key pressed * will be returned ASAP to read(). @@ -839,15 +856,16 @@ static int linenoiseEdit(char *buf, size_t buflen, const char *prompt) * initially is just an empty string. */ linenoiseHistoryAdd(""); - int pos1 = getCursorPosition(); if (write(out_fd, prompt,l.plen) == -1) { return -1; } flushWrite(); - int pos2 = getCursorPosition(); - if (pos1 >= 0 && pos2 >= 0) { - l.plen = pos2 - pos1; - } + + /* If the prompt has been registered with ANSI escape sequences + * for terminal colors then we remove them from the prompt length + * calculation. */ + l.plen = prompt_len_ignore_escape_seq(prompt); + while(1) { char c; int nread;