diff --git a/embedded_cli.c b/embedded_cli.c index 6313a20..a594a39 100644 --- a/embedded_cli.c +++ b/embedded_cli.c @@ -146,10 +146,13 @@ const char *embedded_cli_get_history(struct embedded_cli *cli, if (len == 0) return NULL; pos += len + 1; - if (pos == sizeof(cli->history)) + if (pos >= sizeof(cli->history)) return NULL; } + if (cli->history[pos] == '\0') + return NULL; + return &cli->history[pos]; #else (void)cli; @@ -168,7 +171,7 @@ static void embedded_cli_extend_history(struct embedded_cli *cli) if (strcmp(cli->buffer, cli->history) == 0) return; memmove(&cli->history[len + 1], &cli->history[0], - sizeof(cli->history) - len + 1); + sizeof(cli->history) - (len + 1)); memcpy(cli->history, cli->buffer, len + 1); // Make sure it's always nul terminated cli->history[sizeof(cli->history) - 1] = '\0'; @@ -399,7 +402,7 @@ bool embedded_cli_insert_char(struct embedded_cli *cli, char ch) cli_putchar(cli, '\n', true); break; default: - if (ch > 0) + if (ch < 0 || ch >= 32) embedded_cli_insert_default_char(cli, ch); } } diff --git a/embedded_cli.h b/embedded_cli.h index b232e4f..c2bc5f6 100644 --- a/embedded_cli.h +++ b/embedded_cli.h @@ -133,7 +133,7 @@ const char *embedded_cli_get_line(const struct embedded_cli *cli); /** * Parses the internal buffer and returns it as an argc/argc combo - * @return number of values in argv (maximum of EMBEDDED_CLI_MAX_ARGC) + * @return number of values in argv (maximum of EMBEDDED_CLI_MAX_ARGC - 1) */ int embedded_cli_argc(struct embedded_cli *cli, char ***argv); diff --git a/examples/posix_demo.c b/examples/posix_demo.c index 30b0142..e500faf 100644 --- a/examples/posix_demo.c +++ b/examples/posix_demo.c @@ -95,7 +95,8 @@ int main(void) cli_argc = embedded_cli_argc(&cli, &cli_argv); printf("Got %d args\n", cli_argc); for (int i = 0; i < cli_argc; i++) { - printf("Arg %d/%d: '%s'\n", i, cli_argc, cli_argv[i]); + printf("Arg %d/%d: [%lu bytes] '%s'\n", i, cli_argc, + strlen(cli_argv[i]), cli_argv[i]); } done = cli_argc >= 1 && (strcmp(cli_argv[0], "quit") == 0); diff --git a/tests/embedded_cli_test.c b/tests/embedded_cli_test.c index b080ec5..e62b4bf 100644 --- a/tests/embedded_cli_test.c +++ b/tests/embedded_cli_test.c @@ -18,6 +18,7 @@ #define CTRL_L "\x0c" #define CTRL_R "\x12" #define CTRL_U "\x15" +#define CTRL_X "\x18" static void cli_equals(const struct embedded_cli *cli, const char *line) { @@ -214,6 +215,8 @@ static void test_multiple(void) {"abc" LEFT LEFT CTRL_L "\n", "abc"}, {"abc" CTRL_U "\n", ""}, {"abc" LEFT LEFT CTRL_U "\n", "bc"}, + // The check below ensures we ignore unknown control sequences + {CTRL_X " " CTRL_X " " CTRL_X "\n", " "}, {NULL, NULL}, }; @@ -300,22 +303,36 @@ static void test_max_chars(void) TEST_ASSERT(cli.buffer[sizeof(cli.buffer) - 2] == 'f'); } -TEST_LIST = { - {"simple", test_simple}, - {"argc", test_argc}, - {"delete", test_delete}, - {"cursor_left", test_cursor_left}, - {"cursor_right", test_cursor_right}, +static void test_utf8(void) +{ + struct embedded_cli cli; + char **argv; + embedded_cli_init(&cli, NULL, NULL, NULL); + test_insert_line(&cli, "normal ñ ü 中文 text\n"); + int argc = embedded_cli_argc(&cli, &argv); + TEST_ASSERT(argc == 5); + TEST_ASSERT(strcmp(argv[0], "normal") == 0); + TEST_ASSERT(strcmp(argv[1], "ñ") == 0); + TEST_ASSERT(strcmp(argv[2], "ü") == 0); + TEST_ASSERT(strcmp(argv[3], "中文") == 0); + TEST_ASSERT(strcmp(argv[4], "text") == 0); +} + +TEST_LIST = {{"simple", test_simple}, + {"argc", test_argc}, + {"delete", test_delete}, + {"cursor_left", test_cursor_left}, + {"cursor_right", test_cursor_right}, #if EMBEDDED_CLI_HISTORY_LEN - {"history", test_history}, - {"history_keys", test_history_keys}, - {"search", test_search}, - {"up_down", test_up_down}, + {"history", test_history}, + {"history_keys", test_history_keys}, + {"search", test_search}, + {"up_down", test_up_down}, #endif - {"multiple", test_multiple}, - {"echo", test_echo}, - {"quotes", test_quotes}, - {"too_many_args", test_too_many_args}, - {"max_chars", test_max_chars}, - {NULL, NULL}, -}; \ No newline at end of file + {"multiple", test_multiple}, + {"echo", test_echo}, + {"quotes", test_quotes}, + {"too_many_args", test_too_many_args}, + {"max_chars", test_max_chars}, + {"utf8", test_utf8}, + {NULL, NULL}}; \ No newline at end of file