[PATCH v2 2/2] cli: Correct handling of invalid escape sequences in cread_line()

Simon Glass sjg at chromium.org
Sun Feb 5 03:08:55 CET 2023


The second call to cli_ch_process() is in the wrong place, meaning that
the one of the characters of an invalid escape sequence is swallowed
instead of being returned.

Fix the bug and add a test to cover this.

Signed-off-by: Simon Glass <sjg at chromium.org>
Reported-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---

Changes in v2:
- Fix a failling test

 common/cli_readline.c |  3 +--
 include/cli.h         |  4 ++--
 test/common/cread.c   | 45 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/common/cli_readline.c b/common/cli_readline.c
index 709e9c3d38b..e83743e90c9 100644
--- a/common/cli_readline.c
+++ b/common/cli_readline.c
@@ -284,10 +284,9 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len,
 			}
 
 			ichar = getcmd_getch();
+			ichar = cli_ch_process(cch, ichar);
 		}
 
-		ichar = cli_ch_process(cch, ichar);
-
 		/* ichar=0x0 when error occurs in U-Boot getc */
 		if (!ichar)
 			continue;
diff --git a/include/cli.h b/include/cli.h
index c777c90313f..094a6602d70 100644
--- a/include/cli.h
+++ b/include/cli.h
@@ -98,8 +98,8 @@ int cli_readline(const char *const prompt);
  *
  * @prompt:	Prompt to display
  * @buffer:	Place to put the line that is entered
- * @timeout:	Timeout in milliseconds, 0 if none
- * Return: command line length excluding terminator, or -ve on error: of the
+ * @timeout:	Timeout in seconds, 0 if none
+ * Return: command line length excluding terminator, or -ve on error: if the
  * timeout is exceeded (either CONFIG_BOOT_RETRY_TIME or the timeout
  * parameter), then -2 is returned. If a break is detected (Ctrl-C) then
  * -1 is returned.
diff --git a/test/common/cread.c b/test/common/cread.c
index 3dce4bdb0ef..2fdd29a265f 100644
--- a/test/common/cread.c
+++ b/test/common/cread.c
@@ -46,3 +46,48 @@ static int cli_ch_test(struct unit_test_state *uts)
 	return 0;
 }
 COMMON_TEST(cli_ch_test, 0);
+
+static int cread_test(struct unit_test_state *uts)
+{
+	int duration;
+	ulong start;
+	char buf[10];
+
+	/*
+	 * useful for debugging
+	 *
+	 * gd->flags &= ~GD_FLG_RECORD;
+	 * print_buffer(0, buf, 1, 7, 0);
+	 */
+
+	console_record_reset_enable();
+
+	/* simple input */
+	*buf = '\0';
+	ut_asserteq(4, console_in_puts("abc\n"));
+	ut_asserteq(3, cli_readline_into_buffer("-> ", buf, 1));
+	ut_asserteq_str("abc", buf);
+
+	/* try an escape sequence (cursor left after the 'c') */
+	*buf = '\0';
+	ut_asserteq(8, console_in_puts("abc\e[Dx\n"));
+	ut_asserteq(4, cli_readline_into_buffer("-> ", buf, 1));
+	ut_asserteq_str("abxc", buf);
+
+	/* invalid escape sequence */
+	*buf = '\0';
+	ut_asserteq(8, console_in_puts("abc\e[Xx\n"));
+	ut_asserteq(7, cli_readline_into_buffer("-> ", buf, 1));
+	ut_asserteq_str("abc\e[Xx", buf);
+
+	/* check timeout, should be between 1000 and 1050ms */
+	start = get_timer(0);
+	*buf = '\0';
+	ut_asserteq(-2, cli_readline_into_buffer("-> ", buf, 1));
+	duration = get_timer(start) - 1000;
+	ut_assert(duration >= 0);
+	ut_assert(duration < 50);
+
+	return 0;
+}
+COMMON_TEST(cread_test, 0);
-- 
2.39.1.519.gcb327c4b5f-goog



More information about the U-Boot mailing list