Skip to content

[Feature][Shell] 增加对 Home、Insert、Delete 和 End 键的支持,改进输入模式处理 #10595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 92 additions & 11 deletions components/finsh/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,10 @@ static void finsh_thread_entry(void *parameter)
* down key: 0x1b 0x5b 0x42
* right key:0x1b 0x5b 0x43
* left key: 0x1b 0x5b 0x44
* home : 0x1b 0x5b 0x31 0x7E
* insert : 0x1b 0x5b 0x32 0x7E
* del : 0x1b 0x5b 0x33 0x7E
* end : 0x1b 0x5b 0x34 0x7E
*/
if (ch == 0x1b)
{
Expand Down Expand Up @@ -676,6 +680,66 @@ static void finsh_thread_entry(void *parameter)
}
}
#endif /*defined(FINSH_USING_WORD_OPERATION) */
else if (ch >= 0x31 && ch <= 0x34) /* home(0x31), insert(0x32), del(0x33), end(0x34) */
{
shell->stat = WAIT_EXT_KEY;
shell->line[shell->line_position + 1] = ch; /* store the key code */
Comment on lines +685 to +686
Copy link
Preview

Copilot AI Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storing the key code at shell->line_position + 1 could cause buffer overflow or corrupt user input data. The shell->line buffer is used for command input and overwriting it with key codes can lead to unexpected behavior. Consider using a separate temporary variable to store the key code.

Suggested change
shell->stat = WAIT_EXT_KEY;
shell->line[shell->line_position + 1] = ch; /* store the key code */
shell->stat = WAIT_EXT_KEY;
shell->ext_key_code = ch; /* store the key code in a dedicated variable */

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新增一个没必要 在line的缓存区申请中就已经有个多余的字节放在了最后 可以利用起来 不会产生越界操作

continue;
}
}
else if (shell->stat == WAIT_EXT_KEY)
{
shell->stat = WAIT_NORMAL;

if (ch == 0x7E) /* extended key terminator */
{
rt_uint8_t key_code = shell->line[shell->line_position + 1];
Copy link
Preview

Copilot AI Aug 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading the key code from shell->line_position + 1 is problematic because this location in the buffer may contain user input data or be out of bounds. This creates a dependency on the previous problematic storage at line 686 and could lead to incorrect key code interpretation.

Suggested change
rt_uint8_t key_code = shell->line[shell->line_position + 1];
rt_uint8_t key_code = shell_ext_key_code;

Copilot uses AI. Check for mistakes.


if (key_code == 0x31) /* home key */
{
/* move cursor to beginning of line */
while (shell->line_curpos > 0)
{
rt_kprintf("\b");
shell->line_curpos--;
}
}
else if (key_code == 0x32) /* insert key */
{
/* toggle insert mode */
shell->overwrite_mode = !shell->overwrite_mode;
}
else if (key_code == 0x33) /* del key */
{
/* delete character at current cursor position */
if (shell->line_curpos < shell->line_position)
{
int i;

rt_memmove(&shell->line[shell->line_curpos],
&shell->line[shell->line_curpos + 1],
shell->line_position - shell->line_curpos);
shell->line_position--;
shell->line[shell->line_position] = 0;

rt_kprintf("%s ", &shell->line[shell->line_curpos]);

/* move cursor back to original position */
for (i = shell->line_curpos; i <= shell->line_position; i++)
rt_kprintf("\b");
}
}
else if (key_code == 0x34) /* end key */
{
/* move cursor to end of line */
while (shell->line_curpos < shell->line_position)
{
rt_kprintf("%c", shell->line[shell->line_curpos]);
shell->line_curpos++;
}
}
continue;
}
}

/* received null or error */
Expand Down Expand Up @@ -790,27 +854,44 @@ static void finsh_thread_entry(void *parameter)
{
int i;

rt_memmove(&shell->line[shell->line_curpos + 1],
&shell->line[shell->line_curpos],
shell->line_position - shell->line_curpos);
shell->line[shell->line_curpos] = ch;
if (shell->echo_mode)
rt_kprintf("%s", &shell->line[shell->line_curpos]);
if (shell->overwrite_mode) /* overwrite mode */
{
/* directly overwrite the character */
shell->line[shell->line_curpos] = ch;
if (shell->echo_mode)
rt_kprintf("%c", ch);
shell->line_curpos++;
}
else /* insert mode */
{
shell->line_position++;
/* move existing characters to the right */
rt_memmove(&shell->line[shell->line_curpos + 1],
&shell->line[shell->line_curpos],
shell->line_position - shell->line_curpos);
shell->line[shell->line_curpos] = ch;

/* move the cursor to new position */
for (i = shell->line_curpos; i < shell->line_position; i++)
rt_kprintf("\b");
if (shell->echo_mode)
{
rt_kprintf("%s", &shell->line[shell->line_curpos]);
/* move cursor back to correct position */
for (i = shell->line_curpos + 1; i < shell->line_position; i++)
rt_kprintf("\b");
}
shell->line_curpos++;
}
}
else
{
/* append character at end of line */
shell->line[shell->line_position] = ch;
if (shell->echo_mode)
rt_kprintf("%c", ch);
shell->line_position++;
shell->line_curpos++;
}

ch = 0;
shell->line_position ++;
shell->line_curpos++;
if (shell->line_position >= FINSH_CMD_SIZE)
{
/* clear command line */
Expand Down
3 changes: 2 additions & 1 deletion components/finsh/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ enum input_stat
WAIT_NORMAL,
WAIT_SPEC_KEY,
WAIT_FUNC_KEY,
WAIT_EXT_KEY,
};
struct finsh_shell
{
Expand All @@ -66,7 +67,7 @@ struct finsh_shell

rt_uint8_t echo_mode: 1;
rt_uint8_t prompt_mode: 1;

rt_uint8_t overwrite_mode: 1;
#ifdef FINSH_USING_HISTORY
rt_uint16_t current_history;
rt_uint16_t history_count;
Expand Down
Loading