From ef2c6fa8f7daa607fa6b575ca186de31345d87d5 Mon Sep 17 00:00:00 2001 From: Felix Adler Date: Fri, 21 Nov 2025 12:16:54 +0100 Subject: [PATCH 1/2] Fix overflow if history size is integer multiple of entries --- src/include/microrl/microrl_config.h | 2 +- src/microrl/microrl.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/include/microrl/microrl_config.h b/src/include/microrl/microrl_config.h index 4d6c3de..a69b558 100644 --- a/src/include/microrl/microrl_config.h +++ b/src/include/microrl/microrl_config.h @@ -264,7 +264,7 @@ extern "C" { #define MICRORL_VERSION_MAJOR 2 #define MICRORL_VERSION_MINOR 6 -#define MICRORL_VERSION_PATCH 0 +#define MICRORL_VERSION_PATCH 1 #ifdef __cplusplus } diff --git a/src/microrl/microrl.c b/src/microrl/microrl.c index d37ee15..c83f136 100644 --- a/src/microrl/microrl.c +++ b/src/microrl/microrl.c @@ -396,14 +396,13 @@ static void prv_terminal_print_line(microrl_t* mrl, int32_t pos, uint8_t reset) * \param[in,out] idx_ptr: Pointer to the current record */ MICRORL_CFG_STATIC_INLINE void prv_hist_next_record(microrl_hist_rbuf_t* rbuf_ptr, size_t* idx_ptr) { - while (rbuf_ptr->ring_buf[++(*idx_ptr)] != '\0') { + do { + ++(*idx_ptr); + if (*idx_ptr >= MICRORL_ARRAYSIZE(rbuf_ptr->ring_buf)) { *idx_ptr -= MICRORL_ARRAYSIZE(rbuf_ptr->ring_buf); - if (rbuf_ptr->ring_buf[*idx_ptr] == '\0') { - break; - } } - } + } while (rbuf_ptr->ring_buf[*idx_ptr] != '\0'); } /** @@ -480,7 +479,10 @@ static size_t prv_hist_restore_line(microrl_hist_rbuf_t* rbuf_ptr, char* line_st prv_hist_next_record(rbuf_ptr, &idx); } - ++idx; /* Move position from `\0` marker */ + ++idx; /* Move position from `\0` marker and take care of wrap-around*/ + if (idx >= MICRORL_ARRAYSIZE(rbuf_ptr->ring_buf)) { + idx -= MICRORL_ARRAYSIZE(rbuf_ptr->ring_buf); + } size_t rec_len = 0; size_t k = idx; From 20dce4b961005c281f31c6b05a5df4ce7265930f Mon Sep 17 00:00:00 2001 From: Felix Adler Date: Fri, 21 Nov 2025 19:10:55 +0100 Subject: [PATCH 2/2] Feature: add configuration to disable the tokenizer --- src/include/microrl/microrl_config.h | 7 +++++++ src/microrl/microrl.c | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/src/include/microrl/microrl_config.h b/src/include/microrl/microrl_config.h index a69b558..141e878 100644 --- a/src/include/microrl/microrl_config.h +++ b/src/include/microrl/microrl_config.h @@ -97,6 +97,13 @@ extern "C" { #define MICRORL_CFG_PROMPT_COLOR MICRORL_COLOR_GREEN #endif +/** + * \brief Disable the tokenizer to get the full command in the first slot of the argv array + */ +#ifndef MICRORL_CFG_DISABLE_TOKENIZER +#define MICRORL_CFG_DISABLE_TOKENIZER 0 +#endif + /** * \brief Enable it, if you want to use completion functional, also set completion callback in you code. * Completion functional calls 'copmletion' callback if user press 'TAB'. diff --git a/src/microrl/microrl.c b/src/microrl/microrl.c index c83f136..5031845 100644 --- a/src/microrl/microrl.c +++ b/src/microrl/microrl.c @@ -667,7 +667,15 @@ static microrlr_t prv_handle_newline(microrl_t* mrl) { } #endif /* MICRORL_CFG_USE_ECHO_OFF */ +#if MICRORL_CFG_DISABLE_TOKENIZER + tkn_str_arr[0] = mrl->cmdline_str; + tkn_cnt = 1; + status = microrlOK; + (void)prv_cmdline_buf_split; /*avoid declared but never referenced warning */ +#else status = prv_cmdline_buf_split(mrl, tkn_str_arr, &tkn_cnt, mrl->cmdlen); +#endif /* MICRORL_CFG_DISABLE_TOKENIZER */ + if (status == microrlOK) { #if MICRORL_CFG_USE_COMMAND_HOOKS int exec_status = 0;